資料協商的概念
客戶端傳送請求給服務端,客戶端會宣告請求希望拿到的資料的格式和限制,服務端會根據請求頭資訊,來決定返回的資料。
分類
請求 Accept
返回 Content
Accept
Accept 宣告想要資料的型別
Accept-Encoding 資料以哪種編碼方式傳輸,限制服務端如何進行資料壓縮。
Accept-Language 展示語言
User-Agent 瀏覽器相關資訊,移動端、客戶端、pc端的瀏覽器 User-Agent 不同。
Content
服務端返回
Content-Type 對應 Accept,從 Accept 中選擇資料型別返回
Content-Encoding 對應 Accept-Encoding,宣告服務端資料壓縮的方式
Content-Language 對應 Accept-Language,是否根據請求返回語言
瀏覽器請求 html 時的頭資訊
啟動伺服器 node server.js,localhost:8888 埠訪問,test.html先設為空。
// server.js
const http = require('http')
const fs = require('fs')
http.createServer(function (request, response) {
console.log('request come', request.url)
const html = fs.readFileSync('test.html')
response.writeHead(200, {
'Content-Type': 'text/html',
// 'X-Content-Options': 'nosniff'
// 'Content-Encoding': 'gzip'
})
// response.end(zlib.gzipSync(html))
response.end(html)
}).listen(8888)
console.log('server listening on 8888')
複製程式碼
檢視 network 的 localhost 檔案的請求資訊,瀏覽器會自動加上這些頭資訊。
Response Headers
Connection: keep-alive
Content-Type: text/html
Date: Fri, 21 Sep 2018 02:29:16 GMT
Transfer-Encoding: chunked
Request Headers
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Cookie:
Host: localhost:8888
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
複製程式碼
請求頭
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
瀏覽器可以接收這些格式的資料,可以進行設定。
Accept-Encoding: gzip, deflate, br
資料編碼方式,gzip 使用最多;br 使用比較少,但壓縮比高。
Accept-Language: zh-CN,zh;q=0.9
瀏覽器會判斷本系統的語言,自動加上。q 代表權重,數值越大權重越大,優先順序越高。
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
Mozilla/5.0 瀏覽器最早是網景公司出的,當時預設頭是 Mozilla/5.0,很多老的 http 伺服器只支援這個頭,所以加上相容老的 web 伺服器。
AppleWebKit/537.36 瀏覽器核心 ,chrome 和 safari 等現代瀏覽器大部分使用 webkit 核心,webkit 核心是蘋果公司開發的
KHTML 渲染引擎版本,類似於 Gecko,火狐瀏覽器渲染引擎
Chrome/68.0.3440.106 chrome 版本號
Safari/537.36 因為使用了 webkit 核心,所以會加上
服務端根據資料協商的資訊進行判斷,返回客戶端想要的資訊。
在傳送 ajax 請求時可以自定義設定 accept 相關資訊
content type 相關
Accept-Encoding
資料壓縮
請求檔案大小 933B,使用 gzip 壓縮後是 609B
// server.js
const http = require('http')
const fs = require('fs')
const zlib = require('zlib') // 引入包
http.createServer(function (request, response) {
console.log('request come', request.url)
const html = fs.readFileSync('test.html') // 這裡不加 utf8,加了返回的就是字串格式了
response.writeHead(200, {
'Content-Type': 'text/html',
// 'X-Content-Options': 'nosniff'
'Content-Encoding': 'gzip'
})
response.end(zlib.gzipSync(html)) // 壓縮
}).listen(8888)
console.log('server listening on 8888')
複製程式碼
請求檔案響應頭
Response Headers
Connection: keep-alive
Content-Encoding: gzip // 返回的壓縮演算法方式
Content-Type: text/html
Date: Fri, 21 Sep 2018 02:58:54 GMT
Transfer-Encoding: chunked
複製程式碼
Content-type
用來協商客戶端和服務端的資料格式和宣告
傳送請求時,會有不同的請求內容,根據內容不同設定不同的 content-type
chorme瀏覽器設定,勾選 Preserve log,當頁面跳轉後,也會把之前的請求列印出來
傳送表單資料
<body>
<form action="/form" method="POST" id="form" enctype="application/x-www-form-urlencoded">
<input type="text" name="name">
<input type="password" name="password">
<input type="submit">
</form>
</body>
</html>
複製程式碼
Request Headers
Content-Type: application/x-www-form-urlencoded // content-type 就是 form表單中設定的
Form Data
name=sf&password=sfs
複製程式碼
服務端根據 content-type 是 x-www-form-urlencoded來對body 中的資料進行轉化即可。
如果表單資料中有檔案
<body>
<form action="/form" method="POST" id="form" enctype="multipart/form-data">
<input type="text" name="name">
<input type="password" name="password">
<input type="file" name="file">
<input type="submit">
</form>
<script>
var form = document.getElementById('form')
form.addEventListener('submit', function (e) {
e.preventDefault()
var formData = new FormData(form)
fetch('/form', {
method: 'POST',
body: formData
})
})
</script>
</body>
複製程式碼
代表請求是有多個部分的,有時通過表單上傳檔案時,必須要把檔案部分單獨拆分出來,檔案不能作為字串進行傳輸的,要作為二進位制的資料進行傳輸;使用 x-www-form-urlencoded 這種拼接字串的方式 是不對的
Request Headers
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary39Ug3FSPIBvDYZd6
Request Payload
------WebKitFormBoundary39Ug3FSPIBvDYZd6
Content-Disposition: form-data; name="name"
sdfs
------WebKitFormBoundary39Ug3FSPIBvDYZd6
Content-Disposition: form-data; name="password"
sdfs
------WebKitFormBoundary39Ug3FSPIBvDYZd6
Content-Disposition: form-data; name="file"; filename="1536973449110.png"
Content-Type: image/png
------WebKitFormBoundary39Ug3FSPIBvDYZd6--
複製程式碼
boundary=----WebKitFormBoundarybwAbNlPF2bBcTLuA
用來分割表單提交資料的各個部分
服務端拿到表單資料後,根據這個分割字串,進行資料分割。