# Modern Web ## 使用者在瀏覽器上打網址,最後看到一個網頁 當使用者在瀏覽器中輸入一個網址並訪問一個網頁時,背後發生了一連串複雜的過程。這個過程可以大致分為以下幾個階段: ### 1. 輸入網址 - 使用者在瀏覽器的地址欄輸入一個網址(URL),例如 `https://www.example.com`。 ### 2. 域名解析(DNS 查詢) - 瀏覽器首先需要將網址中的域名(如 `www.example.com`)轉換成一個 IP 地址。這是通過一個叫做域名系統 **(DNS)** 的分散式數據庫完成的。 - 如果域名的 IP 地址不在瀏覽器或系統的快取中,瀏覽器會向配置的 DNS 伺服器發出查詢請求。 ### 3. 建立連接 - 獲得 IP 地址後,瀏覽器會向該地址的伺服器發起一個連接請求。對於 HTTPS 網站,這涉及一個稱為 **TLS 握手** 的過程,以建立一個安全的連接。 ### 4. 發送 HTTP 請求 - 一旦連接建立,瀏覽器會通過該連接發送一個 HTTP 請求,請求網站的數據。 ### 5. 伺服器處理請求 - 網站的伺服器接收到請求後,會根據請求的路徑和參數處理這個請求。這可能涉及在伺服器端運行腳本,訪問數據庫等操作。 ### 6. 發送回應 - 一旦伺服器處理完請求,它會向瀏覽器發送一個回應,這通常包括一份 HTML 文件。 ### 7. 加載和解析 HTML - 瀏覽器接收到 HTML 內容後,會開始解析 HTML 代碼,並根據這些代碼渲染頁面。 - 在解析過程中,瀏覽器可能會發現需要額外加載的資源(如 CSS 文件、JavaScript 腳本、圖片等),這些資源會進一步由瀏覽器請求。 ### 8. CSS 處理和 JavaScript 執行 - 加載 CSS 文件後,瀏覽器會對 HTML 元素應用樣式。 - 如果頁面包括 JavaScript,瀏覽器也會加載並執行這些腳本,這可能會改變頁面的結構和外觀。 ### 9. 頁面渲染 - 一旦所有的 HTML、CSS 和 JavaScript 都被加載和執行,瀏覽器會根據這些資源將頁面渲染出來,使用者便可以看到最終的網頁。 ### 10. 使用者互動 - 此時,使用者可以與頁面進行互動,例如點擊鏈接、填寫表單等。這些互動可能會觸發 JavaScript 腳本,進而發出新的 HTTP ## CORS & 如何讓跨網域溝通變得可行 CORS(*Cross-Origin Resource Sharing*,跨來源資源共享)是一種安全功能,允許網頁從與其不同來源(域、協議或埠 port)的伺服器請求資源。它是一種機制,用於放寬瀏覽器的同源政策,該政策預設情況下阻止網頁從不同來源的伺服器獲取資源。 最常見的實現 CORS 的方法是在伺服器端設置適當的 HTTP 響應頭。這些響應頭告訴瀏覽器,從特定來源的頁面可以訪問伺服器的資源。 ```http Access-Control-Allow-Origin: 這個響應頭指定了哪些來源可以訪問資源。例如,設置為 * 允許所有來源的請求,或者指定某個特定的來源。 Access-Control-Allow-Methods: 指定允許的 HTTP 方法(如 GET、POST)。 Access-Control-Allow-Headers: 指定瀏覽器允許在實際請求中使用的標頭。 ``` ```http Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: Content-Type ``` 前端代理:在某些情況下,可以在前端設置代理伺服器,將跨來源請求發送到代理,由代理將請求轉發到目標伺服器。這種方法避免了直接從客戶端到目標伺服器的跨來源請求。 `JSONP`(僅限 `GET` 請求):JSONP 是一種老舊的技術,允許跨來源請求資料。它通過 `<script>`標籤加載來自不同來源的 `JavaScript` 文件。但這種方法僅支持 `GET` 請求,且有安全風險。 - CORS 政策僅適用於瀏覽器環境。如果從伺服器或命令行工具(如 `curl`)發送請求,則不受限制。 - 適當地配置 CORS 非常重要,因為過於寬鬆的設置可能會帶來安全風險。 - 允許所有來源 (*) 可能會使您的伺服器暴露於跨站腳本攻擊( `XSS` )。 - 總之,CORS 是一種安全機制,旨在在不降低網站安全性的前提下,允許網頁跨來源訪問資源。正卻配置 CORS 是確保安全跨來源溝通的關鍵。 ## HTTP 通訊協定 ### HTTP 通訊協定的特性 HTTP( *HyperText Transfer Protocol*,超文本傳輸協定)是用於在網路上傳輸資料的一種應用層協定,運行於 TCP/IP 協定之上。它是現代網際網路互動的基礎,是一種簡單、靈活且廣泛使用的網路協定。 1. **無狀態(Stateless)**: - HTTP 是一種無狀態協定,這意味著每次請求之間都是獨立的,伺服器不會記住前一次的請求。這簡化了互動,也提高了效率;但也意味著如果需要保持狀態,必須採用其他機制(如 cookies)。這帶來了一些限制,尤其是在需要維護用戶狀態的應用中。 2. **連接性(Connectionless)**: - 在 HTTP/1.0 中,預設情況下,伺服器在響應請求後會關閉連接。這稱為無連接性。在 HTTP/1.1 中,引入了持久連接(persistent connection),允許在一次連接中發送多次請求和回應。 3. **可擴展性(Extensible)**: - HTTP 協定設計允許輕鬆擴展。例如,可以通過自定義標頭(headers)和新的方法(如 `PUT`、`DELETE`)來擴展其功能。 4. **基於請求-響應模型**: - HTTP 通訊是基於請求-回應模型的。客戶端(通常是瀏覽器)發送一個請求給伺服器,伺服器處理該請求並返回一個回應。 5. **支持多種資料類型**: - HTTP 可以傳輸各種類型的資料,包括文本、圖像、聲音、影片和二位元資料。通過 `MIME` 類型在 HTTP 響應中指定內容類型。 6. **支持加密傳輸(HTTPS)**: - 通過在 HTTP 上實現 `SSL/TLS`,得到 HTTPS,這為資料傳輸提供了資料加密和安全保證、完整性保護。 7. **支持中介和快取**: - HTTP 允許網路中介(如代理伺服器和快取)處理或暫存資料,這有助於提高效率和減輕伺服器負擔。 ### SSL / TLS 是什麼? SSL(Secure Sockets Layer)和TLS(Transport Layer Security)是用於網際網路通訊的安全技術標準,旨在保護網際網路數據傳輸的安全。它們主要用於網頁瀏覽器和伺服器之間的加密連接,但也可用於其他應用程序。 - **SSL**: 是最初由 Netscape 開發的加密技術,用於保護網際網路通訊免受竊聽和篡改。SSL 通過在傳輸數據時加密信息來工作。 - **TLS**: 是SSL的繼承者,提供更強的安全措施。TLS 使用更先進的加密算法,可以更有效地保護數據。大多數現代的安全通訊實際上是使用 TLS 協議,即使人們仍普遍稱之為 SSL。 兩者的主要目的是確保資料在網際網路上安全地傳輸,防止未經授權的存取和數據竊取。 ### 網路中介(如代理伺服器)是什麼? 網路中介,常見的一種形式是代理伺服器,是一種網路服務,它允許用戶端通過它與其他伺服器進行通訊。代理伺服器的主要功能是中繼數據,並有時候對數據進行處理。 - **功能**: 代理伺服器可以提供各種功能,包括匿名瀏覽、內容過濾、快取資料來加速訪問速度、安全防護等。 - **匿名瀏覽**: 通過代理伺服器訪問網際網路時,目標伺服器收到的是代理伺服器的 IP 地址,而不是用戶的實際 IP 地址。這樣可以增加用戶的隱私保護。 - **內容過濾和安全**: 在企業和教育機構中,代理伺服器經常用來過濾和監控網路流量。它們可以阻止對不適當內容的訪問,並檢查數據以防止惡意軟體傳播。 - **快取功能**: 代理伺服器可以儲存經常請求的資料。當相同的資料再次被請求時,代理伺服器可以從快取中提供這些資料,從而減少延遲和帶寬消耗。 總的來說,SSL/TLS和代理伺服器都是網際網路安全和高效運作的重要組成部分,但它們在功能和目的上有所不同。SSL/TLS專注於加密和數據安全,而代理伺服器則提供數據中繼、隱私保護和其他附加服務。 ## HTTP GET 與 POST 方法的比較 #### 選擇 GET 或 POST - 選擇 GET 還是 POST 方法取決於應用的具體需求。 - 對於簡單的資料檢索,GET 是更好的選擇。 - 對於涉及敏感資料或需要修改伺服器狀態的操作,應該使用 POST 方法。 - 開發者應根據具體情況做出適當的選擇。 #### 方法功能 | 方法 | 功能 | | ------ | ------------------------------------------------------------ | | GET | 用於請求資料,或某個資源的表示形式。通常只用於獲取資料,不應導致資源狀態的改變 | | POST | 用於向指定資源提交資料,或觸發伺服器端的操作。常用於提交表單資料或上傳文件 | #### 資料參數的傳輸 | 方法 | 傳輸方式 | | ------ | ------------------------------------------------------------ | | GET | 將請求參數附加在 URL 上,通常可見於瀏覽器的地址欄中(例如 `?param1=value1&param2=value2`) | | POST | 將資料包含在請求的主體(body)中,不會顯示在 URL 上 | #### 資料大小限制 | 方法 | 大小限制 | | ------ | ------------------------------------------------------------ | | GET | 受 URL 長度限制,適合小量資料的傳輸 | | POST | 一般沒有大小限制,適合大量資料的傳輸,如文件上傳 | #### 安全性和私密性 | 方法 | 安全性 | | ------ | ------------------------------------------------------------ | | GET | 因參數在 URL 中顯示,不適合傳輸敏感資料 | | POST | 資料不顯示在 URL 中,對敏感資料稍微安全,但未加密的 HTTP 連接中資料仍可見 | #### 快取和書籤 | 方法 | 快取與書籤 | | ------ | ------------------------------------------------------------ | | GET | 回應可被快取,且 GET 請求的 URL 可以被書籤 | | POST | 回應一般不被快取,且由於無可見 URL,POST 請求不能被書籤 | #### 幂等性 | 方法 | 幂等性 | | ------ | ------------------------------------------------------------ | | GET | 幂等的,多次執行同一請求效果相同 | | POST | 通常非幂等,每次請求可能對伺服器資源造成更改 | ## 404 與 500,502,503 ### 4xx 狀態碼 | 狀態碼 | 說明 | | ------ | -------------------------------------------- | | 400 | Bad Request - 請求格式錯誤或無法處理的請求 | | 401 | Unauthorized - 請求需要使用者認證 | | 403 | Forbidden - 伺服器拒絕執行請求 | | 404 | Not Found - 請求的資源無法找到 | | 405 | Method Not Allowed - 請求方法不被允許 | ### 5xx 狀態碼 | 狀態碼 | 說明 | | ------ | ---------------------------------------------------- | | 500 | Internal Server Error - 伺服器內部錯誤 | | 501 | Not Implemented - 伺服器不支持請求的功能 | | 502 | Bad Gateway - 作為代理或閘道器的伺服器收到無效回應 | | 503 | Service Unavailable - 伺服器暫時無法處理請求 | | 504 | Gateway Timeout 伺服器作為閘道器時無法及時得到回應 | ## WebSocket 與 HTTP 比較 WebSocket 是一種網路通訊協定,提供了在單個 TCP 連接上進行全雙工通訊的能力。它使得資料可以從客戶端到伺服器,以及從伺服器到客戶端實時且高效地傳輸,適用於需要快速響應的應用,如即時通訊和多人遊戲。 HTTP是用於傳輸超文本(例如網頁)的應用層協定。他基於請求-響應模型,在客戶端和伺服器之間傳輸資訊。是構建網路應用(特別是 World Wide Web)的基礎協定。 WebSocket 和 HTTP 都是網路協定,但它們在通訊方式、連接持久性和適用場景上有顯著差異。WebSocket 適合實時互動的應用,而 HTTP 則適用於傳統的請求-響應式網頁通訊。 | 特性 | WebSocket | HTTP | | ----------- | ---------------------------------------------- | ---------------------------------------------- | | 連接類型 | 全雙工通訊,允許同時進行雙向通信。 | 半雙工通訊,基於請求-回應模型。 | | 持久性 | 連接保持開放,直到被使用者端或伺服器關閉。 | 在 HTTP/1.1 中支持持久連接,但每請求獨立。 | | 用途 | 適合需要快速和持續互動的應用。 | 適用於一般的網頁請求和資料傳輸。 | | 頭信息 | 初始連接時使用 HTTP 頭信息,之後不再需要。 | 每個請求和響應都包含 HTTP 頭信息。 | | 協定轉換 | 初始使用 HTTP,然後升級到 WebSocket 協定。 | 始終使用 HTTP 協定。 | | 特別適用於 | 實時通訊、在線遊戲和即時更新的應用。 | 傳統的網頁請求、文件下載和上傳等。 | ## Cookie #### 定義 Cookie 是由網站伺服器發送到使用者瀏覽器並保存在本地的小型資料片段。它主要用於識別使用者,保存使用者偏好或其他瀏覽器會話 (session) 資訊。 #### 運作方式 1. 當使用者造訪一個網站時,網站伺服器可能會創建一個或多個 cookie。 2. 這些 cookie 被儲存到使用者的瀏覽器中。 3. 每次使用者之後訪問同一網站時,瀏覽器會將儲存的 cookie 一起發送給伺服器,以便伺服器識別使用者或記錄瀏覽器的狀態。 ### Cookie 定義 Cookie 是由網站伺服器發送到用戶瀏覽器的一小段數據。瀏覽器會將這些數據存儲起來,並在之後的每次請求中將其發送回服務器。Cookie 通常用於識別用戶、保存用戶的偏好設置或其他與用戶會話(session)相關的資訊。 ### Cookie 的運作方式 1. **設置 Cookie**: - 當用戶訪問一個網站時,網站的服務器可以通過 HTTP 響應頭(Set-Cookie)向用戶的瀏覽器發送一個或多個 Cookie。 - 例如:`Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2023 07:28:00 GMT;` 2. **儲存 Cookie**: - 用戶的瀏覽器會將這些 Cookie 儲存在本地。每個 Cookie 都有特定的作用域和有效期,這些參數決定了 Cookie 的儲存和發送規則。 3. **發送 Cookie**: - 在之後的每次向同一網站發出的 HTTP 請求中,瀏覽器會自動將該網站的所有相關 Cookie 加入到 HTTP 請求頭中發送給伺服器。 - 例如:`Cookie: id=a3fWa;` 4. **伺服器讀取 Cookie**: - 伺服器根據接收到的 Cookie 資訊,識別用戶或會話狀態,並根據需要進行相應的處理。 ### Cookie 的用途 - **使用者身份驗證**:網站可以利用 Cookie 來記錄和驗證用戶身份。 - **保存使用者偏好**:儲存用戶設置和偏好,如介面的風格或語言選擇。 - **追蹤使用者行為**:用於追蹤用戶在網站上的活動,常用於廣告定向和行為分析。 - **會話管理**:管理用戶的會話狀態,如登入狀態或購物車內容。 ### 注意事項 - **安全性**:Cookie 可能會被用於跟蹤和收集用戶資訊,因此涉及隱私問題。 - **限制**:大多數瀏覽器對 Cookie 的數量和大小有限制。 - **跨站請求偽造(CSRF)**:Cookie 在安全設計上需要考慮防範 CSRF 攻擊。 Cookie 是網路應用中常用的技術,通過在客戶端儲存資料來實現狀態管理和個性化設置,但它也需要謹慎處理,以保護使用者的隱私和安全。 ## Web Storage #### 定義 Web Storage 是 HTML5 提供的一種機制,允許網站在使用者的本地電腦上儲存資料。它分為兩種:`localStorage` 和 `sessionStorage`。 #### 特點 - **localStorage**:用於長期資料儲存,除非用戶清除瀏覽器快取,否則資料不會消失。 - **sessionStorage**:用於一次會話(session)的資料儲存。當用戶關閉標籤頁或瀏覽器後,資料將被清除。 ## Cookie 與 Web Storage 的比較 都遵守同源政策 CORS,儲存在使用者端。 Web Storage 提供了更大的儲存空間和更加靈活的資料管理方式, 而 Cookie 則適用於需要伺服器每次都能讀取的情況。 | 特性 | Cookie | Web Storage | | ------------- | -------------------------------------------- | --------------------------------------------- | | 資料儲存位置 | 伺服器和使用者瀏覽器 | 僅使用者瀏覽器 | | 資料儲存大小 | 較小(一般為 4KB 限制) | 較大(一般至少為 5MB) | | 與伺服器通訊 | 每次 HTTP 請求都會發送 cookie 到伺服器 | 不會自動發送給伺服器 | | 運作方式 | 主要用於追蹤用戶狀態 | 用於儲存大量資料以優化用戶體驗 | | | 資料生命週期 | 可設置過期時間 | `localStorage` 長期儲存 `sessionStorage` 會話儲存 | ## 快取 Cache 的觀念 快取(*Cache*)是一種技術,用於暫時儲存複製資料,以便在未來的請求中快速訪問這些資料。快取可以存在於不同的層級,如:瀏覽器快取、伺服器快取、代理快取等。 #### 快取的主要目的: - **減少延遲**:通過減少資料檢索的時間,提高資料訪問速度。 - **降低帶寬需求**:重複使用已下載的資源,減少對原始資源的重複請求。 #### 快取的運作方式: 1. **首次請求**:用戶首次請求某個資源時,資源從原始位置(如伺服器)獲取並儲存於快取中。 2. **後續請求**:當相同資源再次被請求時,系統會先檢查快取是否存在該資源的副本,並且是否最新。如果是,則直接從快取中提供資源,而不是從原始位置重新獲取。 #### 快取策略: - **過期策略**:定義資源在快取中可存放的時間。 - **驗證策略**:在使用快取的資源之前確認其有效性。 ## RESTful API 的設計原則 RESTful API( *Representational State Transfer* ,表述性狀態傳輸)是一種基於 HTTP 協定的網絡應用程序接口(API)設計風格。 #### 基本原則: 1. **客戶端-伺服器架構**:分離客戶端和伺服器的關注點。 2. **無狀態**:每次請求都應該包含所有必要的資訊,伺服器不應保留任何客戶端的狀態。 3. **可快取**:回應應明確標記為可快取或不可快取,以提高效率。 4. **統一接口**:一致的接口促進不同客戶端與伺服器的互操作性。 5. **分層系統**:系統可能由多個層次的伺服器組成,每層執行特定功能。 6. **按需程式碼(可選)**:伺服器可以臨時擴展客戶端的功能性。 #### 資源導向架構: RESTful API 以資源為中心,每個資源通常有一個相關的 URI。 | HTTP 方法 | 操作 | 說明 | | --------- | ------------ | ----------------------------- | | GET | 讀取 | 獲取資源的表示 | | POST | 創建 | 在伺服器上創建新資源 | | PUT | 更新 / 替換 | 更新現有資源或創建新資源 | | DELETE | 刪除 | 從伺服器上刪除資源 | | PATCH | 部分更新 | 對資源進行部分修改 | RESTful API 的設計應遵循無狀態、客戶端-伺服器分離、統一接口等原則,以提高應用的可維護性、可擴展性和靈活性。 MVC 模式和純函數的概念 ## MVC(Model-View-Controller)設計模式 MVC(Model-View-Controller)是一種用於應用程式開發的架構模式,旨在分離關注點以提高應用的可維護性和擴展性,使得程式碼易於管理和擴展。 ### 工作流程 - 使用者通過視圖 (View) 與應用程式互動。 - 控制器 (Controller) 接收使用者的輸入並處理它。 - 模型 (Model) 負責業務邏輯並發送資料變更的通知。 - 視圖 (View) 根據模型 (Model) 的狀態變更進行更新。 | 組件 | 職責 | | ----------- | ------------------------------------------------------------ | | Model(模型) | 負責業務邏輯和資料(狀態)的管理。通常涉及資料庫的讀寫操作。 | | View(視圖) | 負責顯示資料(模型)或使用者界面。用於呈現資料和接收使用者輸入。 | | Controller(控制器) | 處理使用者的輸入,並調用模型和視圖完成請求的處理。作為模型和視圖之間的協調者。 | TLS(傳輸層安全性協定)握手是一種在客戶端與服務器之間建立安全通信連接的過程。這個過程確保了數據的隱私性和完整性。TLS 握手涉及多個步驟,其主要目的是: 1. 驗證通訊雙方的身份。 2. 協商加密算法和參數。 3. 建立加密通訊的密鑰。 ## TLS 握手 ### 1. 客戶端請求 - **客戶端發送 ClientHello 消息**:包含 TLS 版本、支持的加密套件列表(加密算法和密鑰交換方法)和一個客戶端生成的隨機數。 ### 2. 服務器響應 - **服務器發送 ServerHello 消息**:選擇一組客戶端支持的加密套件和一個服務器生成的隨機數。 - **服務器提供身份證明**:發送其數字證書(通常包含公開密鑰)。 - **服務器密鑰交換**:根據選擇的密鑰交換方法,服務器可能會發送額外的密鑰交換信息。 ### 3. 客戶端響應 - **客戶端驗證服務器證書**:客戶端驗證服務器的數字證書(例如,通過檢查證書是否由可信憑證書頒發機構簽發)。 - **客戶端密鑰交換**:客戶端可能會根據密鑰交換方法發送密鑰信息(如預主密鑰)。 - **客戶端發送 ClientFinished 消息**:表示客戶端握手過程的結束,這通常是第一個加密消息,使用協商好的密鑰進行加密。 ### 4. 服務器最終響應 - **服務器發送 ServerFinished 消息**:也是加密的,表示服務器握手過程的結束。 ### 5. 加密通信開始 - 此時,客戶端和服務器已經共享了一個安全加密的連接,並開始通過這個連接進行加密的數據傳輸。 TLS 握手是一個複雜的過程,涉及多個加密技術和安全措施。其目標是確保雙方能夠安全地交換密鑰信息,並建立一個安全的通信通道,以防止數據被竊聽和篡改。