HTTP 請求的工作原理

從開始到結束,當你在瀏覽器中輸入URL時會發生什麼事情 HTTP協議 我僅分析URL請求 與macOS / Linux相關的事情 DNS查找階段 gethostbyname TCP請求握手 發送請求 請求行 請求標頭 請求主體 響應 解析HTML 本文描述了瀏覽器如何使用HTTP/1.1協議進行頁面請求 如果你曾經參加過面試,可能會被問到:“當你在Google搜索框中輸入內容並按下Enter鍵時會發生什麼”. 這是一個最常問的問題之一。人們只是想看看你是否能解釋一些相當基本的概念,以及你是否對互聯網的工作原理有任何了解。 在這篇文章中,我將分析當你在瀏覽器的地址欄中輸入URL並按下Enter鍵時會發生什麼。 這是一個非常有趣的主題,我可以在單獨的文章中深入探討其中的許多技術。 這項技術很少更改,並且為人類所建造的最複雜和最廣泛的生態系統之一提供動力。 HTTP協議 首先,我特別提到HTTPS,因為使用HTTPS連接的情況有所不同。 我僅分析URL請求 現代瀏覽器具有知道你在地址欄中輸入的是實際URL還是搜索詞的能力,如果不是有效的URL,它們將使用默認搜索引擎。 我假設你輸入的是實際URL。 當你輸入URL並按下Enter鍵時,瀏覽器首先構建完整的URL。 如果你只輸入了一個域名,例如flaviocopes.com,瀏覽器默認會在前面添加 HTTP://,使用預設的HTTP協議。 與macOS / Linux相關的事情 只是提一下。Windows可能會略有不同。 DNS查找階段 瀏覽器開始進行DNS查找以獲取服務器的IP地址。 域名對於我們人類來說很方便,但互聯網根據IP地址對服務器的精確位置進行組織,IP地址是一組類似 222.324.3.1(IPv4)的數字。 首先,它檢查DNS本地緩存,看看域名最近是否已被解析。 Chrome有一個方便的DNS緩存可視化工具,你可以在chrome://net-internals/#dns查看。 如果在那裡找不到任何內容,瀏覽器將使用DNS解析器,使用gethostbyname POSIX系統調用檢索主機信息。 gethostbyname gethostbyname首先在本地主機文件中查找,該文件在macOS或Linux中位於/etc/hosts,以查看系統是否在本地提供該信息。 如果這沒有提供有關該域的任何信息,系統將向DNS服務器發送請求。 DNS服務器的地址存儲在系統首選項中。 下面是兩個常用的DNS服務器: 8.8.8.8:Google公共DNS服務器 1.1.1.1:CloudFlare DNS服務器 大多數人使用由其網絡提供商提供的DNS服務器。 瀏覽器使用UDP協議執行DNS請求。 TCP和UDP是計算機網絡的兩個基礎協議。它們處於相同的概念層級,但TCP是面向連接的協議,而UDP是無連接的協議,更加輕量級,用於以較小開銷發送消息。 如何進行UDP請求不在本教程的範圍內 DNS服務器可能在緩存中有域的IP。如果沒有,它將向樹狀DNS服務器發送請求。這是一個由13台實際服務器(分佈在全球各地)組成的系統,該系統驅動整個互聯網。 DNS服務器不知道地球上每個域名的地址。它只知道頂級DNS解析器的位置。頂級域是域名的擴展名:.com,.it,.pizza等。 一旦根DNS服務器收到請求,它會將請求轉發給頂級域(TLD)DNS服務器。假設你正在尋找flaviocopes.com,根域DNS服務器會返回.com TLD服務器的IP。 現在我們的DNS解析器將緩存該TLD服務器的IP,所以它不需要再次向根DNS服務器請求。 TLD DNS服務器將具有我們正在查找的域的權威名稱服務器的IP地址。 如何做到的?當你購買一個域名時,域名註冊商會向相應的TDL發送名稱服務器。當你更新名稱服務器(例如,當你更換主機提供商時),你的域名註冊商將自動更新此信息。 這些是主機提供商的DNS服務器。通常有不止1個,以作為備份。 例如: ns1.dreamhost.com ns2.dreamhost.com ns3.dreamhost.com DNS解析器從第一個開始,並嘗試查詢你正在查找的域名(包括子域名)的IP。 這是IP地址的終極真相來源。 現在我們有了IP地址,可以繼續我們的旅程。 TCP請求握手 有了服務器的IP地址後,瀏覽器現在可以與服務器建立TCP連接。...

REST API介紹

從REST API創建者和使用者的角度來看,什麼是REST API? API代表應用程式介面(Application Programming Interface),是一個涵蓋許多不同事物的總稱。 我們已經看到瀏覽器如何提供一些API,以可用於我們的函式的形式。 我們已經看到Node.js如何通過其預設模塊為我們提供編程API。 API還表示另一種東西:創建通過可以被多個客戶端訪問的服務,並提供一些特定功能的服務。 廣義而言,我們目前有2類API:REST API和GraphQL API。 還有其他類型的API範式存在,例如SOAP,但它們在JavaScript世界中並不常見。 在本文中,我們將談論REST API。 端點 在REST API中,我們創建了客戶端可以訪問的多個端點。 假設我們想要公開一個人員列表。我們可以創建一個將響應於/people路徑的端點。 如果我們的服務監聽在test.com域上,我們將有test.com/people的URL。 該端點可以提供任何格式的數據,但通常我們使用JSON,這是一種方便的文本格式,用於在兩個服務之間通信數據。 該/people端點可以提供一個人的名字列表,以及每個人的id。這可能是我們用來儲存它們在數據庫中的id。 我們的系統還可以公開另一個我們稱之為/person的端點。它接受唯一標識一個人的id,類似於/person/1的形式。 我們的API將提供有關該人的更多信息,例如年齡、電子郵件和地址。 請注意,在第一個端點中我們沒有任何參數,但這一次我們有一個參數。 參數可以以不同的方式發送,並且並不是所有的端點都用於從服務器發送信息。我們很快就會看到一些其他的端點將用於執行操作。 方法 我提到了/people端點將返回我們系統中的人員列表。 這只是一個簡化,現在是時候進一步研究了。 REST API使用HTTP協議的原則來提供基於使用的HTTP方法的不同功能:GET,POST,PUT,DELETE。 GET是最常用的方法。當客戶端使用GET方法調用我們的API端點時,它表示它希望讀取數據。 GET /people將返回人員列表。 GET /person/1將返回一個人的詳細信息。 當HTTP方法為POST時,意義完全不同。端點將是相同的,但所需的操作將是另一個。 我們作為API構建者可以定義含義是什麼。 例如,我們可以創建一個POST /person端點,當被調用時會在數據庫中創建一個新的人。 它接收來自客戶端的數據,以我們可以選擇的預定義格式。我們很快將通過使用Express來看一個示例。 GET和POST是主要使用的2個方法。 有時我們使用PUT和DELETE:PUT有時用於更新資源,例如更改個人的地址。DELETE用於刪除一個資源。 在其他時候,POST用於除讀取之外的所有操作,其中使用GET。 在這個選擇中我們有自由。 在資源中,我們指的是一個實體,例如在/people的復數形式中的人員,或在/person的單數形式中的一個人。 命名API端點 看看上面我使用的/people和/person。 這些都是名詞。 使用名詞作為端點的名稱,並使用HTTP方法表示動作,被認為是最佳做法。 更新一個人使用POST請求到/person端點。 如果你想創建一個API來發送消息給一個人,你將使用POST請求,使用/message端點,並通過它傳遞數據來識別要發送的人和消息。 一個REST API是無狀態的 REST API是無狀態的。 這意味著它在不同請求之間沒有記憶。 你可以找到大多數API實現一個API密鑰機制,作為追蹤誰在調用API的一種方式,並提供一種監控使用情況並強制限制的方法。 API也可以使用登錄/密碼機制進行保護。在這種情況下,API身份驗證過程將需要考慮到握手過程,以提供一個令牌,然後需要在每個未來的請求中發送它,以識別用戶和正確的授權。 回應 API調用會以兩種形式將回應返回給用戶:HTTP回應狀態碼和HTTP回應正文。 每個HTTP請求都有一個狀態碼。 對於HTTP回應狀態碼,我們有一些慣例:當你使用瀏覽器打開一個網頁時,網頁將返回一個200 OK狀態碼。如果找不到該頁面,則返回404 NOT FOUND狀態碼。 對於我們的API也是如此。 常見的狀態碼有: 200 OK:這是成功的標準 HTTP 請求的標準回應。 201 Created:通常是 POST 請求的回應。請求已完成,並建立了一個新的資源。 400 Bad Request:由於用戶端引起的請求錯誤,服務器無法處理請求。錯誤可以包括錯誤的請求格式、過大無法處理等。 401 Unauthorized:需要身份驗證並且客戶端未經授權。 403 Forbidden:由於各種原因,該資源不可用。如果原因是對身份驗證,請使用401 Unauthorized狀態碼。 404 Not Found:找不到所請求的資源。 405 Method Not Allowed:該資源不能使用該HTTP方法訪問,但可能可以使用其他方法訪問。 500 Internal Server Error:一個通用的啟示服器錯誤消息,當遇到意外情況並且沒有更具體的消息時給出。 你可以在HTTP狀態碼列表中找到完整的列表。值得注意的是,當你創建一個API時,應該始終返回正確的狀態碼,以通知你的用戶。...