您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
建议掌握的HTTP基础知识篇
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
建议掌握的HTTP基础知识篇
自猿其说Tech
2021-02-25
IP归属:未知
141200浏览
计算机编程
>* 靓仔靓女们大家好,我们又见面了,这周来分享一篇关于`HTTP`协议相关的文章 > * 看完此文可以对 > * **HTTP报文格式**、**HTTP各种请求头**,**HTTP响应码**、 **cookie属性**以及**HTTPS为什么安全(涉及到三种加密方式)** 有个清晰的认知 > * **全文五千来字,强烈建议收藏,巩固基础** > * 若文中涉及到的知识点有所偏差的话,还请大佬们指出,小杰感激不尽,冲冲冲!~ ## HTTP简介 * 超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应 * 现在主要应用 http1.1 协议 * http是无状态协议,不会保存多次请求之间的关系,使用`cookie`做状态管理 * 持久连接节省通信量(HTTP1.1和部分HTTP1.0) * 通过请求方法告知服务器意图,`get`,`post`等 ## HTTP报文 > * 用于HTTP协议交互的信息叫做HTTP报文 > * 报文由**报文首部**和**报文主体**来组成,其中由**空行**分割 > * **请求报文**和**响应报文**的**报文结构不一样**,其中最大的区别就是在报文首部中,**各有各的特定的首部** ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210123205448.png) * 报文首部:服务器或者客户端需要处理的请求或者响应的内容及其属性 * 报文主体:被发送的数据 #### HTTP请求报文结构 * 由**客户端**发送的报文叫做**请求报文** ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210123214750.png) * 请求行:包含用于请求的方法,请求URI和HTTP版本 * 请求首部字段:请求报文里特有的字段(后文会提到) * 通用首部字段:请求报文和响应报文都会用到的首部 * 实体首部字段:针对请求报文的实体部分使用的首部 * 其他:可能包含HTTP的RFC里未定义的首部(如Cookie等) #### HTTP响应报文结构 * 由**服务端**发送的报文叫做**响应报文** ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210123214821.png) * 状态行:包含表明响应结果的状态码,原因短语和HTTP版本 * 响应首部字段:响应报文里特有的字段(后文会提到) * 通用首部字段:请求报文和响应报文都会用到的首部 * 实体首部字段:针对响应报文的实体部分使用的首部 * 其他:可能包含HTTP的RFC里未定义的首部(如Set-Cookie等) > 注:若HTTP首部字段重复了的话,不同的浏览器处理机制不一样 > * 有些浏览器会优先处理第一次出现的字段 > * 有些浏览器会优先处理最后一次出现的字段 ## HTTP响应码 #### 2xx 成功 > **2xx**的响应结果就代表请求被正常处理了 * **200 OK**:表示客户端发来的请求被服务器正常处理了 * **204 Not Content**:请求被成功处理,但是返回的响应报文不包含实体的主体部分 * **206 Partial Content**:客户端进行范围请求,而服务器重新执行了这部分的GET请求 #### 3xx 重定向 > **3xx**的响应结果就表明浏览器需要执行某些特殊的处理以正确处理请求 * **301 Moved Permanently**:永久重定向。表示请求的资源已经被分配了新的URI,以后应该使用新的URI * **302 Found**:临时重定向。代表资源只是暂时的移动了以后还可能会移动为新的URI * **303 See Other**:由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源 * **304 Not Modified**:客户端发送附带条件(请求首部中if开头的属性中的一种)的请求的时候,服务端允许访问资源,但是那些请求并没有满足,直接返回304,即服务端资源未改变,可以直接使用客户端未过期的缓存,304返回时,不包含任何响应的主体部分(虽然被划分为3xx里,但是和重定向没有任何关系) #### 4xx 客户端错误 > **4xx**的响应结果就表明客户端是发生错误的原因所在 * **400 Bad Requset**:请求报文中存在语法错误,请修改请求内容后再发送请求 * **401 Unauthorized**:客户端未认证授权 * **403 Forbidden**:服务端禁止客户端访问此资源 * **404 Not Found**:URL写错了,找不到此路径 #### 5xx 服务器错误 > **5xx**的响应结果就表明服务器本身发生错误 * **500 Internal Server Error**:服务器内部故障,可能是bug导致的 * **503 Service Unavaliable**:服务器暂时不可用(停机维护或者超负载),如果事先知道解除这种情况所需的时间,最好写入响应头中的`Retry-After`这个字段再返回给客户端 ## HTTP报文首部 HTTP1.1 规定了 以下47种首部字段 #### 通用首部 (共9种) | 首部字段 |解释 | | --- | --- | | **1.** Cache-Control | 控制缓存的行为 | | **2.** Connection | 逐跳首部、连接的管理 | | **3.** Date | 创建报文的日期和时间 | | **4.** Pragma | 报文指令 | | **5.** Trailer | 报文末端的首部一览 | | **6.** Transfer-Encoding |指定报文主体的传输编码方式 | | **7.** Upgrade | 升级为其他协议 | | **8.** Via | 代理服务器的相关信息 | | **9.** Warning | 错误通知 | 下面我们来看挑几个重要的属性来看下~ 2. Connection 他有两个作用 * 控制不再转发给代理的首部字段 ``` js GET / HTTP/1.1 Upgrade: HTTP/1.1 // 就会把次字段删除后再从代理服务器转发出去 Connection: Upgrade // 不再转发的首部字段名 ``` ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124104507.png) * 管理持久链接(这个比较常见) * HTTP/1.1默认连接都是持久连接`Connction: Keep-Alive` * 当服务器想断开的时候,需要指定`Connction: close` 4. Pragme :是`HTTP/1.1`之前版本遗留的字段,仅仅是为了与HTTP/1.0向后兼容而定义 * `Pragm:no-cache` :通用首部字段,在请求头中,表示所有的中间服务器不返回缓存的资源 * 可是所有的中间服务器都以`HTTP/1.1`为基准的话,可以直接采用 `Cache-Control:no-cache` * 所以一般会发送两个字段`Cache-Control:no-cache` `Pragm:no-cache` #### 请求报文首部 (共19种) | 首部字段 |解释 | | --- | --- | | 1.Accrpt | 用户代理可处理的媒体类型 | | 2.Accrpt-Charset |优先的字符集 | | 3.Accept-Encoding |优先的内容编码 | | 4.Accept-Language | 优先的语言(自然语言) | | 5.Authorization | web认证信息 | | 6.Expect | 期待服务器的特定行为 | | 7.From | 用户的电子邮箱地址 | | 8.Host | 请求资源所在服务器 | | 9.If-Match | 比较实体标记(ETag) | | 10.If-Modified-Since | 比较资源的更新时间 | | 11.If-None-Match |比较实体标记(与If-Match相反) | | 12.If-Range | 资源未更新时发送实体Byte的范围请求 | | 13.If-Unmodified-Since | 比较资源的更新时间(与If-Modified-Since相反) | | 14.Max-Forwards | 最大传输逐跳数 | | 15.Proxy-Authorization | 代理服务器要求客户端的认证信息 | | 16.Range | 实体的字节范围要求 | | 17.Referer | 对请求中URI的原始获取方 | | 18.TE | 传输编码的优先级 | | 19.User-Agent | HTTP客户端程序的信息 | 9. **If-Match**:只有当 `If-Match` 字段值跟 `ETag` 值匹配一致时,服务器才会接受请求 * 它会告知服务器匹配资源所用的实体标记(ETag)值,这时服务器无法使用弱ETag值 * 仅当两者一致时才会执行请求,否则返回`412 Precondition Failed`的响应 * 还可以使用 * 号指定`If-Match`的字段值,如果这样的话,那么服务器将会忽略ETag的值,只要资源存在就处理请求。 10. **If-Modified-Since** : * 若资源更新时间确实在此字段指定时间之后的话,则处理该请求,否则返回`304 Not Modified` * 用于确认代理或客户端拥有本地资源的有效性,若想获取资源的更新日期时间的话可以通过确认首部字段`Last-Modified`来确定 11. **If-None-Match** * 只有在`If-None-Match`的字段值与ETag值不一致时,才可以处理该请求,与前文中提到的`If-Match`作用相反 12. **If-Range** * 他告知服务器若指定的`If-Range`字段值(ETag值或者时间)和请求资源的ETag值或时间一致时,则作为范围请求处理,否则,返回全体资源 13. **If-Unmodified-Since** * 指定的请求资源只有在字段值内指定的日期时间之后未发生更新,才会执行这个请求,否则,返回`412 Precondition Failed`状态响应,与`If-Modified-Since`作用相反 14. **Max-Forwards** * 每次请求转发时数值减一,直到0时返回响应 * 有可能这个请求经过了多台服务器代理转发,如果突然间请求出现了什么问题导致转发失败,而客户端不知道,此时就可以用此属性来定位问题,这个时候我们就可以掌握一个出问题的转发路径,从而方便进一步的排查问题。 16. **Range**: * 对于只需要获取部分资源的范围请求,`Range`字段可以指定获取资源范围`Range: bytes=10001-20000` * 例子中表示请求获取从第10001字节到20000字节的资源 * 服务器处理请求后会返回`206 Partial Content`的响应。无法处理时,则会返回状态码`200 OK`的响应及其全部资源 #### 响应报文首部 (共9种) | 首部字段名 | 解释 | | --- | --- | | 1.Accept-Ranges | 是否接受字节范围请求 | | 2.Age | 推算资源创建经过时间 | | 3.ETag | 资源的匹配信息 | | 4.Location | 令客户端重定向至指定URI | | 5.Proxy-Authenticate | 代理服务器对客户端的认证信息 | | 6.Retry-After | 对再次发起请求的时机要求 | | 7.Server | HTTP服务器的安装信息 | | 8.Vary | 代理服务器缓存的管理信息 | | 9.WWW-Authenticate | 服务器对客户端的认证信息 | 1. **Accept-Ranges** * `Accept-Ranges:bytes` 可以处理范围请求 * `Accept-Ranges:none` 不可以处理范围请求 2. **Age** * 可以告知客户端,源服务器多久之前创建了资源,单位是秒 * 若创建该响应的是缓存服务器,则Age值是指缓存后的响应再次发起发起认证到认证完成的时间值。代理创建响应时必须加上首部字段Age 3. **ETag** > 它是一种可将资源以字符串形式做唯一标识的方式,服务器会为每份资源分配对应的`ETag`值,资源被更新时,`ETag`值也会被更新,并没有统一的算法规则,而是由服务器来分配 * 强`ETag`:无论实体发生多么细微的变化都会改变其值 * 弱`ETag`:只用于提示资源是否相同,只有资源发生了根本的改变才会改变ETag值,这时会在字段值最开始加`W/`, `ETag:W/"XXX"` 4. **Location** * 使用该响应字段可以将响应接收方引导至某个与请求的URI位置不同的资源 * 基本上,该字段配合3XX,Redirection的响应,提供重定向的URI 8. **Vary** >首部字段vary可对缓存进行控制,源服务器会向代理服务器传达关于本地缓存使用方法的命令 * 当代理服务器接收到服务器返回包含Vary指定项的响应后,仅对请求中含有相同Vary指定首部字段的请求返回缓存 * 即使对相同资源发起请求,但是由于Vary指定的首部字段不相同,因此必须从源服务器重新获取资源 * 例如下面这个,如果使用的`Accept-Language:en-us`字段的值相同,那么直接从缓存返回响应,否则从源服务器请求资源后再返回响应 ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124161555.png) #### 实体报文首部 (共10种) | 首部字段名 | 解释 | | --- | --- | | 1.Allow | 资源可支持的HTTP方法 | | 2.Content-Encoding | 实体主体适用的编码方式 | | 3.Content-Language | 实体主体的自然语言 | | 4.Content-Length | 实体主体的大小(单位:字节) | | 5.Content-Location | 代替对应资源的URI | | 6. Content-MD5 | 实体主体的报文摘要 | | 7. Content-Range | 实体主体的位置范围 | | 8. Content-Type | 实体主体的媒体类型 | | 9.Expires | 实体主体过期的日期时间 | | 10.Last-Modified | 资源的最后修改日期时间 | #### 其他字段(cookie等) * cookie,我们下面单独讲这个 ## cookie > * 注 : 文中例子中的各种请求,报文,均来自 [京东物流官网](https://www.jdl.cn/) > * ps:小杰个人挺喜欢JDL的标语的,**有速度,更有温度**,祝JDL越来越好! ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210123213530.png) #### set-cookie | 属性 | 解释 | | --- | --- | | NAME=VALUE | 赋予Cookie的名称和其值(必需项) | | expires = DATE | Cookie的有效期(若不指定则默认为浏览器关闭为止) | | path=PATH | 将服务器上的文件目录作为Cookie的适用对象(若不指定则默认为文档所在的文件目录) | | domin=域名 |作为Cookie适用对象的域名(若不指定则默认为创建Cookie的服务器域名) | | Secure | 仅在HTTPS安全通信时才会发送Cookie | | HttpOnly | 加以限制,使Cookie不能被JS脚本访问,主要目的是为了防止跨站脚本攻击(Cross Site Scripting,XSS)对cookie的窃取 | #### 谷歌浏览器控制台查看cookie ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124222807.png) * cookie中的`thor`和`JSESSIONID`这两个key的后`HttpOnly`属性被打上了√,就表明,此key无法被js脚本访问,防止跨站脚本攻击(Cross Site Scripting,XSS)对cookie的窃取 我们来看下再`console`控制台输入`document.cookie` 得出的cookie无法找到这两个key ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124223602.png) ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124223629.png) ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124223947.png) 因为这个属性`JSESSIONID`比较重要,存储的是sessionId,这个要是被别人拿到的话,别人就可以冒充我在网站上做某些事情了,像我自己一样请求某些数据了 #### postman 模拟拿到cookie后发送请求 ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124224312.png) ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124224415.png) 我把网页上的cookie拿下来,放到postman里测试,发现和我自己在网站上请求数据是一样的 #### cookie存储的地方,清理缓存到底是清理什么? 清理缓存主要就是清理cookie,抹去自己登陆痕迹以及浏览器中的资源缓存,重新请求网站资源 ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124231131.png) ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124230955.png) ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124230928.png) ## HTTP 与 HTTPS #### HTTP不足 * 通信使用明文(不加密),内容可能会被篡改 * 不验证通信方的身份,因此有可能遭遇伪装 * 无法证明报文的完整性,所以有可能已遭遇篡改 #### HTTPS结构 >HTTPS是身披SSL(Secure Socket Layer)外壳的HTTP ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124193353.png) * 在采用SSL后,HTP就拥有了HTTPS的加密、证书和完整性保护这些功能 * 想要了解HTTPS是怎么加密的,得先了解下下面两种提到的加密技术 #### 对称加密原理 * 客户端和服务端约定好用同一把密钥 * 这把密钥可以对数据进行加密/解密 ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124201014.png) > * 客户端和服务端之间的共享密钥的传送问题也是一个问题,如果能够安全传送不被截获的话,那岂不是数据也可以安全的传送到不被截获?鸡生蛋蛋生鸡的问题。 >* 图中客户端和服务端传输加密数据的时候,如果双方的共享密钥泄露的被黑客截取到的话,黑客就可以用它来解开这加密的数据,所以对称加密不安全 #### 非对称加密原理(公开密钥加密) * 一共有两把密钥(是一对),一个公开密钥,一个私人密钥 * 公开密钥加密的数据,只有对应的私钥才可以解密, * 私钥加密的数据,公钥也可以解密 ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124204038.png) > * 问题就是,从服务端发送给客户端数据时无法保证数据的安全性,因为此时有可能黑客截获到了公钥,对私钥加密的数据进行了解密 > * 服务器端为什么不发送用公钥加密的数据?因为客户端没有私钥,无法解密。 #### 混合加密原理 聪明的大佬们用两种加密算法混合了一下 * 客户端一开始向服务端传输的是,用公开密钥加密的共享密钥! * 这样的话,服务端收到这个加密的数据后用自己的私钥密钥解密后得到的就是共享密钥,以后和客户端交互时都用这个共享密钥就可以啦,因为黑客是无法获得这个共享密钥的,毕竟公开密钥加密的数据,只有对应的私钥才可以解密,而这个私钥一开始就在服务端手里而不在黑客手里 ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124204321.png) 我曾经以为这样就万无一失了,文章也就到此结束了,可以和血包杀手愉快的timi了,可是,你有没有听说过,**中间人攻击**? #### 中间人攻击 >黑客拦截”用公开加密密钥机密后的共享密钥“后不是解密不了吗,好,那我就不拦截这个了,我拦截第一个请求好吧,我拦截服务端传给你的公开密钥,我拦截到了,我再给你个假的,(像极了《让子弹飞》中,张麻子与马邦德的关系,出任鹅城县长)。从根上就伪装成你,以后就等于我是个中间人(中转站),所有的请求,数据都要经过我,那我就可以记录下来其中你的敏感数据,可怕。 ![](https://oncexhj.oss-cn-beijing.aliyuncs.com/image_20210124211155.png) * 其实中间人攻击还要有好多种,以后有机会写一写,我们先大概了解下是什么意思就好~ #### 数字证书 * 所以现在问题又到了这里,我无法确保这个公钥是服务端发给我的,还是中间人发给我的?可这世上没有用钱解决不了的问题,虽然我确保不了,可是有人可以确保,就是得花钱,我们可以使用由数字证书认证机构(CA)和其他相关机构颁发的公开密钥证书 * 数字证书认证机构处于客户端和服务器双方都信赖的第三方机构的立场上。有兴趣的同学可以自行去了解下~ * **所以HTTPS靠非对称性加密及数字证书保证了安全性** ## 写在最后 > * 此文章从**HTTP报文结构**开始,到**HTTP首部**,到**返回状态码**,到**cookie**,再延伸到**HTTPS加密方式**,每一部分都进行了详细的介绍,希望对大家有用! **点赞、在看、收藏、分享**。 * 原创不易,实需鼓励 * **非常欢迎** 各位号主读者一起交流学习,互相开白转发,**网络一线牵,珍惜这段缘** > **若文章有误欢迎指出**,靓仔靓女们,我们下篇文章见 ------------ ###### 自猿其说Tech-JDL京东物流技术发展部 ###### 作者:中台技术部 邢焕杰 ![](//img1.jcloudcs.com/developer.jdcloud.com/89b7559f-4087-40d4-b8b3-260f5ff2b83520210225165025.png)
原创文章,需联系作者,授权转载
上一篇:唯快不破?Redis 迁移同步过程中的挑战与解决方案
下一篇:http与https原理分析
相关文章
Taro小程序跨端开发入门实战
Flutter For Web实践
配运基础数据缓存瘦身实践
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
最新回复
丨
点赞排行
共0条评论
自猿其说Tech
文章数
426
阅读量
2149964
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号