iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
Modern Web

Fastify 101系列 第 5

[Fastify] Day05 - HTTP Header

  • 分享至 

  • xImage
  •  

大家好,我是 Yubin

本篇文章會介紹 HTTP Header 的基本知識,以及透過 Fastify 要如何控制 HTTP Header。

當我們定義了一個像這個 route 之後

server.get('/', async (request, reply) => {
  return reply.status(200).send({
    message: 'Hello World'
  })
})

把 app 跑起來,假設開在本機的 8888 port 上,用瀏覽器打開 localhost:8888/
可以看到 {"message":"Hello World"} 的訊息。

https://ithelp.ithome.com.tw/upload/images/20220920/20151148ZALryILrhD.jpg

為什麼我們會看到這樣的訊息呢?

瀏覽器做了什麼

我們只是在瀏覽器的網址列,敲入一串文字,就可以看到訊息,為什麼。

在 Web 的世界,HTTP 是一個常見的通訊協定,我們可以基於這個協定跟別人要求東西,如果別人願意回應你,你就可以透過這個協定收到東西。

由於一般人要自己處理 HTTP 這個通訊協定非常麻煩,因此我們藉由一個代理工具 (User Agent) 來幫我們操作 HTTP Protocol,這個工具就是我們熟悉的瀏覽器。

HTTP 這個通訊協定定義了一些欄位,請求方可以在這些欄位上描述自己的要求 (request),發送給別人。別人收到後,只要照著 HTTP 協定定義的格式做回覆,就可以讓對方收到回應 (response)。

HTTP Header

我們打開瀏覽器的開發者工具 (大部分瀏覽器是按 F12),來觀察一下 HTTP Header。

https://ithelp.ithome.com.tw/upload/images/20220920/20151148DtA26iiinV.jpg

可以明確看到的是,所謂的 HTTP Header,本質上就是一些文字。

Request Headers

GET / HTTP/1.1,第一行描述了這個 request 使用的 HTTP Method,這邊採用的是 GET
/ 表示要拿的目標資源位置,HTTP/1.1是採用的 HTTP 協定版本。

Host: localhost:8888,表示目標主機的位址。
瀏覽器發出請求後,會將 domain name 轉換成 ip address,這之間的轉換可能是查主機上的對應表,或去跟 DNS 伺服器做詢問。

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0
這邊表示了這個 agent 的版本,目前我用的是 Linux 上的 Firefox。這個欄位的資訊在一些行銷、分析工具 (像 Google Analytics) 常常會被蒐集起來做分析,但這不可靠,可以自己隨便改。

Connection: keep-alive 維持 transaction 的連線,可以減少 TCP 重新連線的次數。

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8,表示此 request 接受哪些 response 的回應格式,此案例為任何格式的回應都接受。

Response Headers

HTTP/1.1 200 OK,回應的 HTTP 版本為 1.1,狀態碼是 200,狀態為 OK

content-type: application/json; charset=utf-8,回應內容的格式為 json,字元編碼為 utf-8

content-length: 25,回應內容的長度 (大小) 為 25 bytes。

Date: Tue, 20 Sep 2022 14:07:21 GMT,回應的時間。

可以看到,基本上這些 Headers 就是一些 Key-Value Pair。

HTTP Method

HTTP 協定定義了一些方法,每個方法有其代表的含意,這邊整理一些常見的方法。

  • GET
    請求資源。
  • POST
    提交資源。
  • PUT
    取代資源。
  • DELETE
    刪除指源。
  • OPTIONS
    描述資源的溝通方法。
  • PATCH
    部份修改資源。

詳細參考 MDN: HTTP Method

我們透過瀏覽器的網址列,送出的請求,就是 GET 請求。

在 Fastify 的程式中,我們定義了有 GET / 這樣的 route,表示只要有一個 GET 方法而且目標是 / 的 request 進來,我就會去處理他,處理的方法是 async (request, reply) => { ... } 這個函式。

於是瀏覽器送出請求給 Fastify 後,Fastify 就會收到 request,根據定義的處理函式。

return reply.status(200).send({
  message: 'Hello World'
})

reply.status(200) 會回應狀態碼 200
.send() 定義要回應的 Payload,Fastify 會把物件轉換為 JSON 格式的字串,並設定 content-type: application/json 來做回應。

自訂 Response Header

透過 reply.headers() 可以自行定義想要的 headers。要定義自己的 Header 也是可行的。

server.get('/', async (request, reply) => {
  reply.headers({ 'Content-Type': 'text/html' })
  return reply.status(200).send('Hello World')
})

https://ithelp.ithome.com.tw/upload/images/20220920/20151148FstPLEofUX.jpg

HTTP Status Code

Status Code,狀態碼是用來代表 HTTP 回應內容狀態的三位數數字。

一般我們耳熟能詳的可能會聽到 404 Not Found200 OK

狀態碼很多,大致可以分成五類

1xx

代表請求已被接受,需要繼續處理 (Continue)。

2xx

代表請求成功 (Successfully)。

3xx

表示需要重新導向 (Redirect)。

4xx

表示用戶端的錯誤 (Client Error)。

5xx

表示伺服端的錯誤 (Server Error)。

詳細參考 MDN: HTTP response status codes

每個狀態碼都有其不同含意,身為良好的後端開發者,我們要準確回應相應的狀態碼。

自訂 HTTP Status Code

根據需要,可以透過 reply.status() 設定想要回應的狀態碼

server.get('/', async (request, reply) => {
  return reply.status(404).send({
    message: 'Hello World'
  })
})

https://ithelp.ithome.com.tw/upload/images/20220920/20151148h8CrlUwAoA.jpg

如上範例,雖然可以自由設定要回傳的狀態碼,但因為每個狀態碼都有其代表的含意,許多工具也對這些狀態碼有不同的預設動作。

例如說,許多工具或函示庫收到 4xx/5xx 的狀態碼,就會視為這個請求失敗了,即使伺服器端有回應正常的 Payload,也會當作這個動作沒有成功,而開始進行例外處理。

正確的使用狀態碼是非常重要的。


上一篇
[Fastify] Day04 - Fastify-CLI
下一篇
[Fastify] Day06 - Route
系列文
Fastify 10130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言