Blog Cover Image

Inspire you to have New thinking, Walk out your unique Road.

有的時候,你無意間遇到的一些故事,會激發你的靈感,改變你的想法,接下來你會用與之前全然不同的觀念去創造屬於你獨特的故事。

Sign @MinaYu.

[前端小菜鳥] 前端工程師成長計畫 - 讀書篇(1) | Internet

Posted on

第一篇讀書計畫的主題是網路Internet。

Internet的知識作為前端工程師的Roadmap第一區塊的知識,描述了網路的基本概念、HTTP協議、前後端如何溝通等相關知識,無論是前端還是後端,在最一開始都是面試最常被詢問的面試題,甚至是以此知識展開圍繞的其他概念,常常都是重要的核心概念。(想當初我就有被問爆幾次,還好現在要重新走一次這條路,知道這塊很重要Q.Q)。

除了原本規劃的知識之外,也會補上一些前幾年在後端打滾遇到的一些經驗以及想到一些相關的後端知識也想一併補充在下面。


本來是有想將自己讀書的內容開一個Github的Repo存放,確實有開但我發現維護困難,加上我時常搞不太清楚該怎麼分層如何分類,後來就想說改成以文章方式撰寫。


本日讀書項目

可以點擊項目跳到對應的內容。

詳請可參考完整讀書計畫目錄


第一區 - 網路(Internet)基本知識

關於基本概念與術語 Basic Concepts and Terminology

  • Packet (封包): A small unit of data that is transmitted over the internet. (簡單來說資料是由一個一個小小的封包傳入網路)
  • Router (路由): A device that directs packets of data between different networks. (路由器能將資料在不同的網路中傳遞)
  • IP Address (IP位置): A unique identifier assigned to each device on a network, used to route data to the correct destination. (每個電子裝置都賦予像是地址位置的IP, 範例 191.232.1.11)
  • Domain Name (網域): A human-readable name that is used to identify a website, such as google.com. (就是賦予IP人類看得懂的名字,稱作網域)
  • DNS (域名系統): The Domain Name System is responsible for translating domain names into IP addresses. (域名系統是對應各個網域及IP位置)
  • HTTP: The Hypertext Transfer Protocol is used to transfer data between a client (such as a web browser) and a server (such as a website). (HTTP是一種傳輸協議,在客戶端與伺服器端傳輸資料,關於更多傳輸協議可找wiki)
    • 同層次的傳輸協議還有: FTP(傳輸資料), SMTP (通常用作寄信), MQTT (目前IoT物聯網感測器相關使用的溝通協議)
  • HTTPS: An encrypted version of HTTP that is used to provide secure communication between a client and server. (加密過後的HTTP協議,稱作 HTTPS)
  • SSL/TLS: The Secure Sockets Layer and Transport Layer Security protocols are used to provide secure communication over the internet. (一種加密協議,用作加密網際網路傳輸,使其擁有安全的網路溝通)

參考網站: https://cs.fyi/guide/how-does-internet-work


補充知識: 網際網路七層模型 - OSI Model

  • 應用層(application layer: HTTP, HTTPS, MQTT
  • 表現層(presentation layer)
  • 會議層(session layer)
  • 傳輸層(transport layer)
  • 網路層(network layer)
  • 資料連結層(data link layer)
  • 實體層(physical layer)

第二區 - Inernet Connection

幾種協議 (Protocols) 跟溝通方式 HTTP Requests, Server-Sent Event, 雙向溝通技術 WebSockets。補充: MQTT, SOAP, GraphQL

這是我在LinkedIn上看到的圖,這些是比較常用的協定,有興趣可以深入探索,我也會在下面補充

有鑒於面試篇提及很多關於網路的知識,早期的我作為後端工程師對這些網路知識並沒有太多設略,但後來發現了解網路知識不但對面試或者是實作,無論是前端還是後端都很實用,是熱門的面試考題。

既然面試篇有提到 Protocol,那邊這篇先從各項協議 Protocols開始介紹。


HTTP/HTTPS 協議

HTTP (HyperText Transfer Protocol),是一種居於OSI模型第七層應用層的協議,此協議提供傳輸資料像是HTML頁面、圖片、影音,為 請求 - 回應 (request - response)模型 傳輸模式,透過HTTP/HTTPS協定請求的資源取得內容。

每一個HTTP需求都是獨立,並沒有任何儲存的狀態。


HTTP Request (單向溝通技術 - 由客戶端發出)

是一種基於 HTTP/HTTPS 協議的單向溝通技術,客戶端通過向伺服器端發送請求,來取得資源,伺服器端則回應該請求。

目前較常用於前後端分離的狀態,後端實作不同的API來提供前端請求資料,而前端向後端的API發出請求 (Call APIs)。

而其HTTP 方法有: GET、POST、PUT、DELETE 來進行溝通。


HTTP request 由三個部分組成

  • Starting line (Request line)
  • Headers
  • Message body
  1. Starting line (Request line): defines the type of the message.
GET /api/index.html HTTP/1.1
  • the method is GET
  • the path is /api/index.html
  • the HTTP version is HTTP/1.1
  1. Headers: characterize the message body, transmission parameters, and other information.
Accept-Language: fr, de
If-Modified-Since: Fri, 10 Dec 2004 11:22:13 GMT
  1. Message body: contains the actual data of the message. It must be separated from the headers by an empty line.

Server-Sent Events (SSE) (單向溝通技術 - 由伺服器端發出)

(還沒碰過任何 SSE 的經驗) SSE是基於HTTP/HTTPS協議的單向溝通技術,被納入HTML5標準的API,其概念是由伺服器端發出需求,由客戶端接收更新訊息,一但連線建立後,就只能接收Server端來的訊息。最常見的場景是需要即時的訊息更新、或者不間斷的單向資料串流。

網路上有看到前輩們分享的SSE經驗,有興趣可以拜讀:

第二篇文章有提及,基本上由於WebSockets的雙向溝通技術太強大了,所以SSE比較少人提及,SSE能做到的事,WebSockets可以做得更好。

不過,像某些應用上不需要客戶端向伺服器端送出請求,只需要一直接收伺服器端的更新的話,這時就只需要運用SSE的單向溝通技術來達成就好。自己也歷經許多專案的磨練,加上自己的命理服務的實作經驗,有的時候如果能用更簡單更單一的技術解決,就不用硬是應用一些功能多及更複雜的技術。針對服務的需求提出最適當的方案才是最好的~。


RESTFul API

RESTful(Representational State Transfer)其實是一種架構風格,在後端實踐APIs時,希望開發者基於RESTful的架構撰寫程式。

使用 HTTP 方法(GET、POST、PUT、DELETE)來執行 CRUD 操作,而API的終端點以 URL 進行識別,通常返回 JSON 或 XML 格式的資料。


TCP協議、三次握手、四次握手

TCP協議位於OSI模型的第六層表現層,以理論上來說,TCP協議是確保在兩個端點之間建立和維護可靠的數據傳輸,所以其特性為連線一但通過建立後,其連線就會一直保持,直到斷開。

三次握手和四次握手(揮手)是TCP建立與斷開連線的過程。

  • 三次握手: 為TCP協議建立連線的過程。
  • 四次握手(揮手): 為TCP協議斷開連線的過程。

WebSockets

WebSockets是基於TCP協議上可雙向溝通的一種技術,通常比較常使用在需要大量即時應用的場景,比方說聊天應用、遊戲、即時通訊。

與HTTP不同,WebSockets連接一旦建立,可以持續存在,並且可以在任何時候雙向傳送資訊。(由於我也沒什麼經驗碰過WebSockets,所以這個時候就可以斗膽猜測魔獸世界只要經過最一開始的登入頁面,登入等同連線建立,那之後的角色列表跟進入遊戲冒險應該都是不間斷的資料傳輸囉!?)

詳細應用可參考網站:JavaScript | WebSocket 讓前後端沒有距離


HTTP Requests vs Websockets

HTTP主要基於 Client-Server Model,也就是由客戶端傳需求至伺服器端,再由伺服器端收到需求後處理完回傳回應(Response),每次HTTP需求都是獨立且斷開,而且只能由客戶端發送單向請求。

Websockets則是適合資料即時串流以及雙向資料傳輸,建立在TCP協議的穩定連線上,使資料能夠雙向交流,且確保資料能夠穩定傳輸。

協議 HTTP WebSocket
連線方式 HTTP 是一種短連線協定,每次請求都需要建立新的連線。 WebSocket 是一種長連線協定,在建立連線後,客戶端和服務器可以一直保持連線狀態。
通訊方式 HTTP 是一種單向通訊協定,只能由客戶端向服務器發送請求。 WebSocket 是一種雙向通訊協定,客戶端和服務器都可以互相發送資料。
資料格式 HTTP 只能傳輸文字資料。 WebSocket 可以傳輸文字資料、二進位制資料其他類型資料
應用場景 HTTP 通常用於 Web 瀏覽檔案下載等應用。 WebSocket 通常用於即時通訊流媒體等應用。
優點 簡單易用、通用性強 效率高、延遲低
缺點 效率低、延遲高 複雜度高、通用性弱

HTTP 和 WebSocket 都是用於在客戶端和服務器之間傳輸資料的協定。HTTP 是一種簡單易用、通用性強的協定,但效率低、延遲高。WebSocket 是一種效率高、延遲低的協定,但複雜度高、通用性弱。在實際應用中,可以根據應用需求選擇合適的協定。


UDP

UDP(User Datagram Protocol)是使用者資料報協定,是一種簡單的面向資料包的通信協定,位於OSI模型的傳輸層(第6層)。

UDP與TCP(Transmission Control Protocol)是兩種最常用的傳輸層協定。TCP是一種可靠的協定,它會在發送端和接收端之間建立連線,並在傳輸資料時進行錯誤檢查和糾正。UDP則是一種不可靠的協定,它不會在發送端和接收端之間建立連線,也不進行錯誤檢查和糾正。

UDP的優點是效率高、延遲低。由於UDP不需要進行錯誤檢查和糾正,因此其傳輸效率比TCP高。此外,UDP也不需要建立連線,因此其延遲比TCP低。

UDP的缺點是不可靠。由於UDP不進行錯誤檢查和糾正,因此其傳輸的資料可能會丟失或損壞。

UDP通常用於以下應用:

  • 即時通訊: 即時通訊應用需要低延遲,因此通常使用UDP協定。

  • 流媒體: 流媒體應用需要高效率,因此通常使用UDP協定。

  • 遊戲: 遊戲應用需要低延遲,因此通常使用UDP協定。


TCP vs UDP

TCP 和 UDP 是兩種是最常用的「傳輸層」(第六層)協定。

協議 TCP UDP
解說 TCP 是一種可靠的協定,它會在發送端和接收端之間建立連線,並在傳輸資料時進行錯誤檢查和糾正。 UDP 則是一種不可靠的協定,它不會在發送端和接收端之間建立連線,也不進行錯誤檢查和糾正。
優缺點 TCP 的優點是可靠,能夠保證資料的完整性和正確性。TCP 的缺點是效率低、延遲高。 UDP 的優點是效率高、延遲低。UDP 的缺點是不可靠,資料可能會丟失或損壞。
運用場景 Web 瀏覽: Web 瀏覽需要傳輸大量資料,並且需要保證資料的完整性和正確性,因此通常使用 TCP 協定。 即時通訊: 即時通訊應用需要低延遲,因此通常使用 UDP 協定。
電子郵件: 電子郵件需要傳輸重要資訊,因此需要保證資料的完整性和正確性,因此通常使用 TCP 協定。 流媒體: 流媒體應用需要高效率,因此通常使用 UDP 協定。
檔案傳輸: 檔案傳輸需要保證資料的完整性和正確性,因此通常使用 TCP 協定。 遊戲: 遊戲應用需要低延遲,因此通常使用 UDP 協定。
實際運用案例 Web 瀏覽器(HTTP)、電子郵件(SMTP)、檔案傳輸(FTP)、遠端登入(Telnet)、資料庫存取(SQL) 即時通訊(VoIP)、域名解析(DNS)、簡單網路管理協定(SNMP)、流媒體(RTP、RTCP)、遊戲

在實際應用中,可以根據應用需求選擇合適的協定。如果需要保證資料的完整性和正確性,則應使用 TCP 協定。如果需要高效率或低延遲,則應使用 UDP 協定。


MQTT 通訊協議

有幸在作為軟體工程師的職涯中遇到IoT物聯網領域的專案,所以特別補充這項溝通協議。

台灣其實是電子產業很蓬勃發展的國家,在未來會有更多物聯網應用相關的服務需要被建立。MQTT協議是在物聯網領域中被廣泛使用作為感測器資料溝通的方式,他是一種輕量且基於發布(Publish)/訂閱(Subscribe)的消息協定,由於大部分的電子感測器裝置都會被安置在環境、狀況不良的地方,而MQTT的協議是專為低帶寬、高延遲或不穩定網路環境而設計。

關於MQTT的技術,有興趣可以參考我撰寫的路燈裝置物聯網應用的文章,打個比方的話像是裝置在路燈內的感測器,他可能外殼面臨風吹雨打,可能為在網路不穩的區域,所以這個時候只要感測器有資料想送出、網路允許時,就趕緊資料都送往MQTT的伺服器端 (可以稱作Broker)的某個頻道(Topic),Broker會將接收到的資料存取 (與其說存取,不如說資料會存在一個Queue裡,對有訂閱Topic的客戶端發送訊息)。這個時候客戶端(就是資料接受端/網頁或軟體端)可以訂閱 MQTT Broker特定的主題 (Topic)來接收這些感測器的資料。

MQTT的Broker (可以想像成伺服器端),可以擁有不同的主題(Topic)用來接收不同的感測器資料。

參考的實作案例,可以參考這篇:


既然扯到跟網路相關的內容,基於以下這張圖,我想特別來補充兩個額外的技術


補充: SOAP

SOAP 是一種基於XML的協定,使用XML格式來定義消息的格式與結構,可以運行於HTTP, SMTP, TCP 協定上,通常會運用於企業級的網站、或者內部網站對接。

常見於大企業的內部網站資料交流使用,雖然後來RESTful的架構比較常運用,但SOAP的協議還是會運用在一些大公司或傳統的公司內部系統使用。

<?xml version="1.0"?>

<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">

<soap:Header>
...
</soap:Header>

<soap:Body>
...
  <soap:Fault>
  ...
  </soap:Fault>
</soap:Body>

</soap:Envelope>

補充: GraphQL

初次見面時是在玩基於Vue.js框架延伸出來的靜態生產網站(SSG): Gridsome,在Gridsome中讀取.md檔資料就是使用GraphQL。

根據維基百科的描述,GraphQL是Facebook為不同的API而創造出來的資料查詢操作語言,大概在2015年左右公開發佈,算是蠻新興的技術,估計要整個紅起來或發展起來還需要些許時間,但可能成為一種未來的流行。

一些主要特點是

  • 可以獲取特定量的資料數據,減少過度傳輸,提高效率。
  • 在一個請求中可以獲得多個資料數據向,提高性能。
  • 他是強型別模式,所以能明確的理解資料結構跟類型。
  • … 更多

不過之前在玩Gridsome的時候發現沒辦法傳輸中文(Unicode)的資料,不知道後續的版本會不會支援。

有時間的話不妨可以花些時間了解GraphQL,也許會在未來的專案中遇到。


第三區 - Internet and API Calls: SWR, react-query, Axios, Ajax

上面提及了基本的網路知識以及幾項網路溝通的協議及方式,這個區塊想探索跟學習的是偏向前端如何向後端溝通,偏實作層面,是我想要著重於前端探索的部分。

這一區塊主要是在React Roadmap下方的區塊API Calls出現,和網路溝通有相關,所以我將它移至這裡學習。

在這個區塊中,我加上了Ajax這個名詞,主要是我本人並不了解這個詞彙,以及我還記得我四年前剛開始找第一份工作的面試時,當時的Challedge Assessment就有被要求用Ajax請求資料。這四年都是擔任後端工程師,並沒有機會接觸前端的作業,所以特地將Ajax擺在此。

API Calls: SWR, react-query, Axios, Ajax

來釐清這幾個單字,用List來寫關聯的話,會是這樣的:

他們的共通點就是,都是發HTTP Requests 跟 Server端溝通。


Ajax

Ajax的全名叫做「Asynchronous JavaScript and XML」(非同步的JavaScript與XML技術)。

如果不知道什麼是非同步(Asynchronous)跟同步(Synchronous)的觀念,建議去理解一下,在前端跟後端的領域都有機會遇到。

簡單來說,同步的觀念就是前端今天向後端發送一個Request請求資料,必須得等到資料回來才渲染頁面,有強烈的先後順序。非同步的概念就是發送Request請求資料後,我可以先渲染頁面,等到資料回傳後再將資料呈現出來。

回到Ajax技術,查詢資料時,被說是一個上古時期的原生物件。

  • 他是很早期前端技術剛發展時,能夠支援前後端溝通的技術
  • JavaScript原生的技術,不需要安裝任何其他函式庫。
  • 注意的一點是雖然叫做「and XML」,但實際上可以使用XML, Json跟HTML格式溝通。

程式碼大致上長這樣


// From w3schools
function loadDoc(url, cFunction) {
  var xhttp;
  xhttp=new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      cFunction(this);
    }
  };
  xhttp.open("GET", url, true);
  xhttp.send();
}
function myFunction(xhttp) {
  document.getElementById("demo").innerHTML =
  xhttp.responseText;
}

JQuery Ajax

JQuery 大家應該都很熟悉,但是呢我跟他不熟,我在認真學習前端時,就幾乎沒遇到Jquery。JQuery是基於JavaScript撰寫的一個函式庫,他運用JavaScript寫了很多函式,用途是讓使用者能更輕鬆方便的製作網站功能 (你想要手刻旋轉木馬(Carousel)呢?還是有人幫您想好呢?反正我是手刻,因為我還看不懂JQuery嗚嗚),而且是免費的。

JQuery Ajax 就是JQuery改良後的Ajax。

  • 基於Ajax原生的XHR物件開發,改良XHR本身架構不清晰的問題,取代原生XHR物件成為主流的Ajax語法結構。
  • 目前還有許多開發者為了使用JQuery Ajax,而導入JQuery函式庫
  • [缺點] 要使用JQuery就要把整個函式庫導入,整包項目Size太大,3.5.1版本就有281KB,連min版都有88KB
  • [缺點] 要實作或者解決跨網站的HTTP要求(cross-site HTTP request)與CORS(Cross-Origin Resource Sharing)不容易做。

fetch API

後續開發出來的Call API技術,基於JavaScript語言運用Promise物件的概念實作。被稱為現代的Ajax的替代方案。

  • 使用ES6的Promise物件做回傳的處理
  • 可以搭配 async/await
  • 不須引入函式庫
  • 可以直接呼叫定義的Request物件
  • 可以用Headers物件設定表頭
  • [缺點] 需要使用catch做錯誤(error)的捕捉與處理
  • [缺點] 只要伺服器端有回應,都會回傳成功的Promise物件,要自行判斷回應的HTTP Code跟內容。
  • [缺點] IE不支援 (很重要蛤)

Reference: request的方式? ajax & fetch & axios

實作Code長相


fetch(file)
.then(x => x.text())
.then(y => myDisplay(y));

// async
async function getText(file) {
  let myObject = await fetch(file);
  let myText = await myObject.text();
  myDisplay(myText);
}

有趣的是,我剛剛在我的React.js專案裡看到我當初誤打誤撞運用的fetch技術來Call後端API

const response = await fetch(ROUTE_API + "/api/v2/", {
    method: "POST",
    body: JSON.stringify(body),
});

if (!response.ok) {
    // Error
    throw new Error('Network response was not ok');
}

const data = await response.json();
return data;

axios

axios 看起來…,算是這一列基於 JavaScript語言中,擁有以上的優點跟優化以上的缺點的技術。

  • 使用方法類似於jQuery
  • 支援搭配 async/await
  • 支持Promise觀念
  • 可以在node.js中使用
  • 支援防CSRF
  • 輕量化的技術,約13KB
  • 廣泛的瀏覽器支援
  • 可以取消要求
  • 可以自動轉換JSON資料
  • [缺點] 還是需要使用catch做錯誤的捕捉跟處理

實作的Code

  • install npm install axios
  • 或者 ` ``js

```js

// Post method
axios.post('/login', {
  firstName: 'Finn',
  lastName: 'Williams'
}).then(response => console.log(response.data))

以下兩種方式都是基於React.js框架上運用的技術。

react-query

react-query 是一個 React 函式庫,它提供了一個更高級的 API 來管理數據狀態。

但敝女還沒使用過,所以不方便多做些講解,當初還以為我自己做的react.js專案是使用這個技術,結果剛剛查了程式碼,原來不是,而是使用fetch 囧。

實作範例

import { useQuery } from 'react-query';

const { data, error } = useQuery('users', () => fetch('/api/users'));

if (error) {
  return <div>Error loading users</div>;
}

if (!data) {
  return <div>Loading...</div>;
}

return (
  <ul>
    {data.map(user => (
      <li key={user.id}>{user.name}</li>
    ))}
  </ul>
);

SWR

useSWR 是一個 React Hook,它使用 Axios 函式庫在後台發送 HTTP 請求。

這項技術根據文檔是說會先從cache查詢過期的資料,並同時發送Request請求(驗證資料是否過期或相同),最後得到最新資料。

以下是根據文檔中列出的特性

  • 輕量型可重複使用的HTTP請求技術
  • 減少 cache跟request的重複使用
  • 支援 SSR / ISR / SSG support
  • 支援 TypeScript
  • 支援 React Native

目前看起來是蠻新的技術,很不幸的是敝女也還未使用,大家有空可以翻一下文件,這是繁體中文,可以拉到最底的footer改成英文來看。

實作範例

import useSWR from 'swr'
 
function Profile() {
  const { data, error, isLoading } = useSWR('/api/user', fetcher)
 
  if (error) return <div>failed to load</div>
  if (isLoading) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

以上介紹了這麼多前端 Call APIs 的技術,實際上還是請各位工程師、開發者根據自己的專案跟環境情況來做選擇,畢竟就算我自己寫React.js專案,邊學邊做時,也是無意間使用了fetch技術來Call APIs,而非使用後來介紹的兩個React.js資料請求技術。

在這篇文章中,只會很粗略的帶過,用我喜歡的方式,就是先了解全部的可能性,然後一一細節去研讀跟了解,這樣就能知道未來若遇到不同的專案跟環境,需要運用哪個技術比較適合,並非最新就最好,只有適合。

好啦,那這篇跟網路相關的知識就讀到這,若有任何解釋上的問題,再麻煩糾正我,非常感謝您。