数据协商,即客户端发送给服务端一个请求的时候,客户端会申明希望拿到的数据的格式以及数据相关的一些限制,而服务端会根据这些请求中表示的想要的限制,来进行判断要返回一个怎样的数据。
分类
- 请求 Accept
通过 “Accept” 申明希望的数据的格式
通过 “Accept-Encoding” 申明希望的数据的编码方式(主要用来限制服务端如何进行数据的压缩)
通过 “Accept-Language” 申明希望的语言
通过 “User-Agent” 申明浏览器相关信息(比如移动端,PC端)
- 返回 Content
通过 “Content-Type” 对应数据格式(参考MIME Type)
通过 “Content-Encoding” 对应数据的编码方式
通过 “Content-Language” 对应语言
下面,我们来实验一下。
先是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', 'utf8')
response.writeHead(200, {
'Content-Type': 'text/html'
})
response.end(html)
}).listen(8888)
console.log('serve listening on 8888')
然后是 test.html ,如下。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>MyHtml</title>
</head>
<body>
<div>hello world</div>
<div>don't speak</div>
</body>
</html>
然后,我们启动项目,访问localhost:8888 。打开控制台 network 会看到:(q 代表权重)
其他点:
关于 Content-Type,我们可以会用到一个Response Header “X-Content-Type-Options”,如下。(在很早之前,返回了Content-Type申明了一种数据类型,IE 浏览器也会不接受而主动地预测返回的数据是怎样的类型,这会导致一些安全性问题,申明了这个头且值为‘nosniff’ 浏览器就不会那么做了)
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', 'utf8')
response.writeHead(200, {
'Content-Type': 'text/html',
'X-Content-Type-Options': 'nosniff'
})
response.end(html)
}).listen(8888)
console.log('serve listening on 8888')
数据压缩
我们先看看未压缩的时候数据的大小,localhost 是 455B
压缩代码,如下
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')
response.writeHead(200, {
'Content-Type': 'text/html',
'Content-Encoding': 'gzip'
})
response.end(zlib.gzipSync(html))
}).listen(8888)
console.log('serve listening on 8888')
我们重启服务,查看文件的大小如下。
最后,发送请求时的“Content-Type”(实际上是会在response阶段体现的)
我们在html页面上新建表单如下。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>MyHtml</title>
</head>
<body>
<div>hello world</div>
<div>don't speak</div>
<form action="/form" method="POST" enctype="application/x-www-form-urlencoded">
<input type="text" name="name"/>
<input type="password" name="password"/>
<input type="submit" />
</form>
</body>
</html>
那么我们就可以看到下面这样的network
当我们要传文件的时候,可以这样
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>MyHtml</title>
</head>
<body>
<div>hello world</div>
<div>don't speak</div>
<form id="form" action="/form" method="POST" enctype="multipart/form-data">
<input type="text" name="name"/>
<input type="password" name="password"/>
<input type="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>
</html>