HTTP报文的头部字段 | 青训营笔记

259 阅读7分钟

这是我参与「第四届青训营 」笔记创作活动的第3天

HTTP——篇②

写在前面

(1)文章摘要

  1. 为什么要有头部字段
  2. 常见的请求头
  3. 常见的响应头
  4. 表单上传文件

(2)读前须知

  1. 阅读本文前,推荐可以先阅读HTTP——篇①

  2. 主要有这些内容:HTTP的版本、报文格式、还有一些定义规范的语言。

一、HTTP的头部字段综述

(1)为什么要有头部字段

1、我们先来思考以下几个问题

  • 要来了解HTTP的头部字段,为什么要有头部字段呢?
  • 一开始的HTTP,没有头部字段,不也可以获取资源吗?
  • HTTP的头部字段那么多,都需要了解吗?
  • HTTP为什么还可以手动扩展头部字段?

2、场景代入

  • 先来说一个场景:Ciusyan 想和 Space 交朋友。
  • 刚认识的时候,知道对方的名字、大致长相就可以了。
  • 随着不断接触,双方都想深交, 这时候,双方都得互相了解。
  • 所以 Ciusyan 写了一段自我介绍(请求头字段),给 Space
  • Space 回复了一段信息(响应头字段),内容可能对 Ciusyan 的某些介绍做了回复,也可能是对自己做了些描述。
  • 他们对自己的描述,可以有很多方式、描述的点,没必要都了解,也不可能了解全。知道一些常见的特点就行了。
  • 他们也可以自己协商一些东西,比如说一起去玩Ciusyan带食物,Space带饮料
  • 如下图:(先不用看每一个字段的含义)

image-202208031356948

3、场景理解

  • 综上场景所述,头部字段,主要是拿来描述请求和响应的特点,比如说(浏览器信息、消息发送时间、消息体类型、允许请求的域等等)
  • 客户端请求描述得清楚,服务器的应答也更加便利。
  • 而那么多的头部字段,也没必要都了解,知道一些常用的就可以了。
  • 也可以自己拓展头部字段,只要和服务器约定好(比如说用Token来做会话管理)

(2)头部字段分类【了解】

  • 头部字段可以分为4种类型
  • 但是也不用管这么多,了解一下就行了
  • 把重心放在请求头、和响应头字段即可
  • 像实体头、通用头字段,基本上就是请求头和响应头中都可以有的字段

1、请求头字段(Request Header Fields)

  • 有关获取资源或者客户端本身信息的消息头

2、响应头字段(Response Header Fields)

  • 有关响应的补充信息,比如说(服务器本身名称、和版本等)的消息头

3、实体头字段(Entity Header Fields)

  • 有关实体主体的更多信息,比如说(主体长度、MIME类型等等)

4、通用头字段(General Header Fields)

  • 同时适用于请求和响应消息,但是与消息主体无关的消息头

二、HTTP的请求头(Request Header)

  • 我下面说到的请求头,只是常见的。还有更多的可以查看文档。
  • 譬如这就是一段消息的请求头
Host: 127.0.0.1:36677
Connection: keep-alive
Content-Length: 105
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Typora/1.0.2 Chrome/91.0.4472.164 Electron/13.6.1 Safari/537.36
Content-Type: text/plain;charset=UTF-8
Accept: */*
Sec-Fetch-Site: cross-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN

(1)User-Agent

  • 浏览器的身份标识字符串
  • 示例
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Typora/1.0.2 Chrome/91.0.4472.164 Electron/13.6.1 Safari/537.36
  • 平时去一些网站,根据不同的操作系统,它返回的资源可能不一样,比如(Nodejs官网怎么知道我是windows电脑的?)
image-20220803131255641

(2)Host

  • 服务器的域名、端口号
  • 示例
Host: 127.0.0.1:36677
  • 一般情况都会用 Host + Uri,去请求特定的资源

(3)Date

  • 发送该消息的日期和时间
  • 示例
Date: Wed, 03 Aug 2022 01:52:07 GMT

(4)Referer

  • 表示浏览器所访问的前一个页面正是前一个页面的某个链接将浏览器带到了当前这个页面
  • 示例
Referer: http://localhost:8080/ciusyan/html/login.html

(5)Content-Type

  • 请求体的类型
  • 示例
content-type: application/json;charset=utf-8
Content-Type: application/x-www-form-urlencoded
Content-Type: text/plain
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryhCc4MA9wykk0zUrT

(6)Content-Lenght

  • 请求体的长度,以字节为单位
  • 示例
Content-Length: 234

(7)Accept

  • 能够接受的响应体的类型
  • 示例
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
  • q代表权重,值越大,优先级越高
  • 如果不指定q值,默认是最大值1.0

(8)Accept-Charset

  • 能够接受的字符集
  • 示例
Accept-Charset: GB2312,utf-8;0.7,*;q=0.7

(9)Accept-Encoding

  • 能够接受的编码方式列表
  • 示例
Accept-Encoding: gzip, deflate, br

(10)Accept-Language

  • 能够接受的响应内容的自然语言列表
  • 示例
Accept-Language: zh-CN,zh;q=0.9

(11)Range

  • 告知服务器返回文件的哪一部分。在一个 Range 首部中,可以一次性请求多个部分,服务器会以 multipart 文件的形式将其返回。如果服务器返回的是范围响应,需要使用 206 Partial Content 状态码。假如所请求的范围不合法,那么服务器会返回 416 Range Not Satisfiable 状态码,表示客户端错误。服务器允许忽略 Range 首部,从而返回整个文件,状态码用 200
  • 示例
Range: bytes=500-999

(12)Connection

  • 该浏览器想要优先使用的连接类型
  • 示例
Connection: keep-alive

(13)跨域相关、缓存相关、Cookie相关

  • Origin、Cookie、Cache-Control在后面单独说。

三、HTTP的响应头(Response Header)

  • 我下面说到的响应头,只是常见的。还有更多的可以查看文档。
  • 譬如这就是一段消息的响应头
Accept-Ranges: bytes
ETag: W/"395-1659496169118"
Last-Modified: Wed, 03 Aug 2022 03:09:29 GMT
Content-Type: text/html
Content-Length: 395
Date: Wed, 03 Aug 2022 03:09:33 GMT
Keep-Alive: timeout=20
Connection: keep-alive

(1)Date

  • 发送该消息的日期和时间
  • 示例
Date: Wed, 03 Aug 2022 01:52:07 GMT

(2)Server

  • 服务器名称
  • 示例
server: Tengine

(3)Last-Modified

  • 所请求的对象的最后修改日期
  • 示例
Last-Modified: Tue, 02 Aug 2022 00:38:23 GMT

(4)Expires

  • 所请求的对象的最后修改日期
  • 示例
Expires: Thu, 01 Jan 1970 00:00:00 GMT

(5)Content-Type

  • 响应体的类型
  • 示例
content-type: application/json;charset=utf-8

(6)Content-Lenght

  • 响应体的长度,以字节为单位
  • 示例
Content-Length: 22

(7)Content-Disposition

  • 一个可以让客户端下载文件,并且可以建议文件名的头部
  • 示例
Content-Disposition: attachment;filename=ciusyan.txt
  • 下图是在一个接口中设置了Content-Disposition后,访问该接口时,浏览器弹出了一个下载文件的框。

image-20220803134953778

(8)Content-Ranges

  • 这一条部分消息,是属于完整消息的哪一个部分
  • 示例
Content-Ranges: bytes 21010-47021/47022

(9)Accept-Ranges

  • 服务器支持哪些种类的部分内容范围
  • 示例
Accept-Ranges: bytes

(10)Location

  • 用来重定向,或者在创建了某个新资源时使用。
  • 我们都知道,以前的路由跳转,是由后端控制的。
  • 现在前后端分离之后,基本上都是前端路由的。
  • 而重定向就可以实现路由跳转。
  • 重定向就是靠 Location + Status
  • 示例
Location: https://www.baidu.com/
  • 可以看到,左右两个请求,效果完全一样。这就是一个重定向的过程。

image-20220803141726760

(11)Connection

  • 针对该连接,所预期的连接类型
  • 示例
Connection: close

(12)跨域相关、缓存相关、Cookie相关

  • Access-Control-Allow-Origin、Set-Cookie、Cache-Control在后面单独说。

四、表单文件上传

  • 请求方法method=“POST”

  • 请求体:enctype=“multipart/form-data”

  • 这里就不描述了,有兴趣的可以看看以前写的一篇文章

  • Form文件上传

写在后面

(1)本文引用

(2)读后思考

  • 读完本文,相信你对头部字段有了一定的认识,可以试着思考一下
    • HTTP跨域相关的问题。我将在HTTP——篇③中说到这个问题。
    • 以前写的一篇表单文件上传,可以实践一下。
    • 看看请求体中的参数,是如何进行传递的?