---
# System prepended metadata

title: '[IM017] How a browser works (4) - HTTP request'
tags: [javascript, ironman]

---

# [IM017] How a browser works (4) - HTTP request

> **前言**
> 2020 秋天，我將用 30 天的時間，來嘗試回答和網路前端開發相關的 30 個問題。30 天無法一網打盡浩瀚的前端知識，有些問題可能對有些讀者來說相對簡單，不過期待這趟旅程，能幫助自己、也幫助讀者打開不同的知識大門。有興趣的話，跟著我一起探索吧！

![](https://images.unsplash.com/photo-1522542550221-31fd19575a2d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80)

## HTTP

在上一篇文章中，我們簡單談到了網路的傳輸架構 (TCP/IP model)，以及 Transportation Layer 當中的 TCP 與 UDP 之間的差異。今天我們要回過頭來，看看在 Application Layer 當中最常見的 HTTP。

當我們在瀏覽器當中輸入網址後，會

1. 透過 DNS server 找到 IP address
2. 建立 TCP/IP 連線 (3-way handshake)

當通訊連線確認之後建立，就會正式送出 HTTP 請求。

HTTP 本身就是一種協議，全名是 Hypertext Transfer Protocol 超文本傳輸協議，當年由 Tim Berners-Lee 發起，提供一個可以發布和接受 HTML 文件的方法，其實也就是發布與接收網頁資訊的方法。

在 [MDN](https://wiki.developer.mozilla.org/en-US/docs/Web/HTTP/Overview) 上介紹的 HTTP 特點如下：

**HTTP 簡單易懂**

HTTP 本身的內容與操作方式都相對簡單（相較於其他的 protocols）讓開發者可以很容易上手。

**HTTP 具備擴展性**

要在 client 和 server 端使用哪一種 HTTP，只要在 HTTP headers 調整就行。這讓開發者可以很容易調整，並嘗試實驗新版本的 HTTP。

**HTTP 是 stateless 但不是 sessionless**

每一次的 HTTP 連線都是獨立的，因此 server 不會知道上一次同樣 client 的請求內容與狀態。不過可以透過在 HTTP headers 當中加入 cookies，使 server 能夠記錄並判斷同一個 client 的 "session"

**HTTP 的連線**

HTTP 並沒有規定要使用哪一種連線方式 (e.g., TCP or UDP)，只有假設其連線方式可以保證連線品質，不會遺失資訊。不過為了確保品質，因此 HTTP 基本上都是建立在 TCP 連線之上。不過也開始有人嘗試在 UDP 上建立 HTTP 連線。

## HTTP message

在 HTTP 通訊中，client 和 server 是透過 HTTP message 來交換資訊。HTTP message 當中包含了：

* Start line
* HTTP headers
* Empty line
* Body

以下分別說明

### Start line

在送出 HTTP request 的時候會在 start line 定義請求方法、請求資源，以及 HTTP 版本，譬如：
```
GET / HTTP/1.1
```

而 server 在回應的時候，則會在 start line 當中放入 HTTP 版本，HTTP 狀態碼與對應的內容。譬如：
```
HTTP/ 1.1 200 success
```

### HTTP headers

在 headers 當中會放入許多和這次通訊相關的資訊，其中包含三大類，分別為 request/response headers, general headers, 以及 unity header。以下分別舉例 request 和 response 時的 HTTP headers

request headers
```
Host: www.google.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
Accept: text/html
Accept-Language: xxx
Accept-Encoding: xxx
```

在 general headers 當中的資訊和連線有關，像是：
```
Connection: keep-alive
Upgrade-Insecure-Requests: 1
```

在 etity headers 當中的資訊，主要和後面 body 所帶的資訊有關，像是：
```
Content-type: multipart/form-data
Content-Length: 666
```

而在 response 時的 HTTP headers 內容會有些不同：

response headers
```
Access-control-Allow-Origin: *
Server: Apache
Set-cookie: xxx=xxx
```

general headers
```
Connection: keep-alive
Date: xxxxx
Transfer-Encoding: xxxxx
```

etity headers
```
Content-type: text/html
Last-modified: xxxxx
```


### Empty line
其實這行的目的，只是代表 HTTP headers 的內容已結束，後面可能有 body 資訊。

### Body
這裡會帶有主要的溝通資訊內容，以 client 來說，可能是表單資訊；對 server 來說，這裡就會帶上要呈現的 HTML 內容

## HTTP request
在 HTTP message 的 start line 中，可以看到這次溝通的請求內容，其中包含「請求方法」和「請求資源」。在 HTTP 當中定義了 9 種方法，常見的有：
* GET - 取得資源
* HEAD - 取得資源，但只取得 response head，不取得 response body 
* POST - 提交資源，通常會在 server 當中創造新的資料或狀態
* PUT - 修改資源，用 request payload 當中的資料複寫該資源當中的內容
* PATCH - 修改資源的部分內容
* DELETE - 刪除該資源

與不常見的：
* CONNECT
* OPTIONS
* TRACE

## End
建立通訊連線之後， 瀏覽器 (client) 就可以發出 HTTP message 向 server 請求資源，這動作也就是發出 HTTP request。而 server 收到請求後，會提供相對應的資源，透過 HTTP message 回傳給 client，這動作就是收到 HTTP response。

下一步，瀏覽器就需要根據 HTTP response 當中的內容，將資訊變成使用者在瀏覽器上面可以看到的畫面。


## Ref
* [前端三十｜30. [WEB] 從輸入網址列到渲染畫面，過程經歷了什麼事情？](https://medium.com/schaoss-blog/%E5%89%8D%E7%AB%AF%E4%B8%89%E5%8D%81-30-web-%E5%BE%9E%E8%BC%B8%E5%85%A5%E7%B6%B2%E5%9D%80%E5%88%97%E5%88%B0%E6%B8%B2%E6%9F%93%E7%95%AB%E9%9D%A2-%E9%81%8E%E7%A8%8B%E7%B6%93%E6%AD%B7%E4%BA%86%E4%BB%80%E9%BA%BC%E4%BA%8B%E6%83%85-49341bcf6aff)
*


***
> **TD**
> Be curious as astronomer, think as physicist, hack as engineer, fight as baseball player
> 
> [More about me](https://tsungtingdu.github.io/profile/)
> 
> *"Life is like riding a bicycle. To keep your balance, you must keep moving."*

***

###### tags: `ironman` `javascript`