可能是最全的http协议总结

Posted 算法和数据结构的峡谷

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可能是最全的http协议总结相关的知识,希望对你有一定的参考价值。

【吐血总结,强烈建议收藏!!!】


导航栏

常用的http状态码HTTP协议头大全ETag Last-Modified Expires 的区别HTTP各种方法http协议的真容分块传送持久连接pipeline管线化无状态性如果不使用https,如何保证http协议传输过程的安全性文件路径攻击DNS 欺骗外部http代理cookieCSRFXSS跨域请求

常用的http状态码

状态 作用
200 最常见的一个code,表示可以访问,或者说是正常访问
201 post方法创建资源的方法,创建成功后返回201
202 这个code表示异步请求,跟nodejs的那个机制很像,就是服务器直接返回一个标志,然后并没有实际的东西,实际的东西需要等待回调函数
301 永远重定向,意思就是只有在第一次才请求服务器,之后都不会请求服务器直接请求浏览器中的缓存,除非删除浏览器中的缓存
302 302是暂时重定向,一般比如引入微信登陆啊,微博登陆啊,用这个,因为它每次的重定向都会再次询问服务器
304 这个标志是指,http的iif-Modified-Since 匹配成功了,然后浏览器直接将浏览器中的缓存给了用户,而不再去访问服务器了
400 参数验证失败
401 用户的权限不够
403 一般就是你被拉入黑名单之类的,你被服务器禁止掉了
404 找不到资源
413 客户端上传的照片资源太大
414 客户端的url过长,导致服务器无法去识别了
500 服务器内部错误
502 服务器挂掉

总之2xx就是好事,3xx就是重xx之类的问题,4xx就是找不到什么什么之类的,或者说就是客户端出问题5xx就是服务器端错误。

HTTP协议头大全


协议头 作用
Accept 【客户端发送的】客户端期待服务器端返回的媒体的格式,逗号分割类型,分号分割属性,举个例子:Accept:audio/*; q=0.1, vedio/basic 意思就是有前面的就用前面的,没有就往后延续找逗号分割。q表示优先级,范围是0-1,这就跟前端css中那个表示层级的一个意思
Accept-Charset 【客户端发送的】这个值表示希望服务器返回的编码,举个例子Accept-Charset:utf-8;q=0.7,gkb;q=0.6;utf-256 q=0.5 假如没有q就是默认q=1
Content-Type 【服务器端返回】这个就常见了把,它代表服务器给浏览器发送的头,代表媒体和编码,其实它就是服务器端对前面俩的应答例如content-Type:text/html;Charset=utf8
Accept-Language 【客户端发】表示期待服务器返回的内容的语言例如 Accept-Language:zh-CN,en-us;q=0.7,zh-HK;q=0.6
Content-Language 【服务器返回】表示对Accept-Language的应答例如 Content-Language:zh-CN,en-us q=0.7
Content-Length 【all】表示传输的请求or响应的body的长度,get不需要,它没有body,携带body的碧玺要有这个字段,知道发送的或者响应的数据大小,当然如果选择了分块传送,这个字段就不用了
Content-Location 【服务器响应】当客户端请求这个资源的时候,这个资源在服务器中还有其他地址也有这个资源,这个字段就是告诉浏览器其这个资源的额其它的地址的
Content-MD5 用来做body内容校验,body内容被md5加密了
Date 【服务器响应】这个字段记录了服务器响应的生成时间,当然如果有缓存就是缓存响应的时间,格式固定不能乱写 格式为:Date: Tue, 15 Nov 2020 03:20:11 GMT
Age 表示资源缓存存在的时间单位是秒 Age: 8900
Expires 【服务器响应】告知资源失效的时间 Expires: Thu ,01 Dec 2020 16:00:00 GMT
ETag 【服务器发送】这个是资源的标签一般是这样的,服务器发给浏览器,浏览器记住了,然后再
if-Match 客户端get到服务器发送的资源的Etag然后记录下来,记录到if-Match中,然后浏览器请求一个资源的时候,会发送这个if-match 如果服务器中的etag跟这个if-math一致的话就可以执行,如果不一致就不执行返回412的错误
if-None-Match 原理一样,但是是这样的,浏览器获取到etag,然后if-none-match记录下来,如果发送过去编码一致,那么就 不去执行,通常这个更改资源的事情会用put或者patch 因为它不存在叠加的状态,下面的method中有介绍
Allow 【服务器发送】表示允许的method Allow:GET,POST
Connection 当浏览器和服务器协商的时候会发送这个属性,比如Connection:close 意思就是断开吧。这个请求结束后不要再长连接了,可以断开了
Expect 向服务器发送东西之前先发送的一个许可,问能不能发啊大哥,这个意思 服务器说行就是100不行就是417
From 这个字段标记浏览器发送的人的邮件的地址
Host 这个是rpc协议中的东西就是假如没有这个字段服务器要抛出400的错误的,
Last-Modified 标记资源最近的修改时间,服务器向浏览器发送,它跟Date的区别是它标记更改修改时间,date是创建时间
if-Modified-Since 如果一个资源浏览器有缓存了,它就会携带if-Modified-Since
if-Unmodified-Since 跟上一个意思相反,当资源不满足的时候不是返回304了,直接返回412错误
Range 支持断点续传,服务器要处理range头因为这个rang记录了每次传的数据 例如 Range: bytes=500-999 那么服务器就记住了,下次从这个地方开始传即可
Content-Range 这是服务器端的,它记录了这个资源的rang在整个资源的区域 例如Content-Range: bytes 21010-47021/47022 这个其实就是最后了为啥是47021不是47022,因为这个值是offset偏移的值,那么是从0开始计算的,所以说最后的那个也是小1的跟数组那个从0计算一个意思的
if-Range 这个就是为了保证断点续传的时候两次的资源是一个资源 if-Range 要带上Etag编号的,可以就是206不可以就是200 就相当于一次新的请求了。例如说你百度下东西,突然服务器那边变了,那么你的资源就会从0开始下载
Location 服务器向客户端发送302跳转的时候会发给浏览器这个location代表了要跳转的地址
Max-Forwards 用来限制最大的转发次数 也就是这个资源经过的不同的网关代理层啥的被转发,这个记录最大的转发的次数,它每次经过一个转发就-1,假如被减去到0了,还没转发到,那么就会不转发了
Pragma 用户开发者模式,当网关收到这个字段的时候即使内部存在该请求资源的缓存并且有效也不可以直接发送给客户端,而必须转发给后面的upstream进行处理
Referer 【浏览器发送】表示请求发起的来源URI,举个例子 你从知乎跳转到了GitHub,那么GitHub就会记录你从哪跳转的,就这个意思。[URL和URN是URI的子集,例如mailto://xxx就是uri但是它不是URL,uri是唯一资源标示符号,URL是统一资源定位符]
Retry-After 假如你的服务器正在升级,那么这个字段就是服务器用来告诉浏览器中要恢复的时间长度,浏览器可能会在这个时间段后去尝试
Server 【服务器返回】返回软件信息,告知浏览器这个服务器是xx公司提供的
User-Agent 这个就是携带的用户代理信息,【浏览器发送】它包换了浏览器名称,浏览器内核,操作系统等版本的信息,跟上面的那个server是一样额都是告知的信息,这样服务器就可以根据不同的user-agent给浏览器不同的信息,比如不同的界面喽
Transfer-Encoding 分块传送的时候,需要添加 Transfer-Encoding:Chunked
Upgrade 【服务器发送】它建议的浏览器使用的http的版本,当使用websocket的时候,三次握手阶段,就会提醒浏览器你跟我通信的时候要使用websocket协议
Vary 【浏览器发送给服务器的参数建议】控制不同的缓存参数用不同的缓存,例如 Vary:Accept-Encoding,Accept-Language ,根据这些参数的不同,服务器在获取来询的请求的时候可以作出不同的判断发送不同的缓存结果,
Via 该字段标示一个请求的经历的不同的网关节点的信息
Warning rpc协议中的东西,【服务器响应】标示给客户端一些警告信息
WWW-Authenticate 401错误的时候携带的头,这个头携带信息给客户端,告诉客户端你准备的东西不够,你要准备这些东西我才让你访问。例如 www-Authenticate: Basic realm=xxx Basic标示base64转换,realme代表场合,情景等信息
Authorization 【浏览器】是浏览器对上面的那个www-Authorizatio的回答,回答的内容就是服务器提出的要求
Proxy-Authenticate 用户认证,用在代理服务器上,服务器给浏览器的问题
Proxy-Authorization 客户端的回答
Cache-Control 【all】no-cache:如果no-cache没有指定值,那就表示不允许缓存。对于请求来说,服务器不得使用缓存内容直接返回。对于响应来说,客户端不得缓存响应的资源内容。如果no-cache指定了值,那就表示值对应的头信息不得使用缓存,其它的信息还是可以缓存的。就是指定了xx不能用,不指定xx就是都不能用  no-store:告知对方不要持久化请求/响应数据到其它地方,这种信息是敏感的,要保持它的易失性。告知对方记录在内存就行了不能记录在硬盘上no-transform 。no-transform告知对方保留原始数据信息,不要进行任何转换。比如不要压缩图片给我,给我原图即可only-if-cached 用于请求头,告知服务器只要那些已经缓存的内容,不要去reload。如果没有缓存内容就返回504,意思就是有缓存你就用,没有就报错。Gateway Timeout 错误。表示客户端不想太麻烦服务器,有就给,没就gg max-age 用于请求头。限制缓存内容的时间,如果超过max-age的,需要服务器去reload内容资源。意思就是如果缓存太老了,我就不要了max-stale 用于请求头。客户端允许服务器返回缓存已过期的资源内容,但是限定了最大过期时间。表示客户端虽然很宽容,那是也是有限度的。min-fresh 用于请求头。客户端限制服务器不要那些即将过期的资源内容。这个值就是给定一个返回,就跟快过期的面包一意思,即使块过期,没过期我都不要,任性。public 用于响应头。表示允许客户端缓存响应信息,并可以给别人使用。比如代理服务器缓存静态资源供所有代理用户使用。private 用于响应头。表示仅允许客户端缓存响应信息给自己使用,不得分享给别人。这样是为了禁止代理服务器进行缓存,而允许客户端自己缓存资源内容。意思就是客户端可以存,但是不能给代理

ETag Last-Modified Expires 的区别

  • ETag 携带的是资源的版本号

  • last-modified 携带资源修改的时间

  • Expires 服务器告知客户端的缓存过期时间客户端根据这个时间自动过期

HTTP各种方法

方法 作用
GET 用的最多,就是请求资源的意思
POST 创建资源(标准就是只是创建,但是我们一般也可以更改)application/x-www-form-urlencoded:提交数据表单时经常使用,Body内部存放的是转码后的键值对。application/json提交结构化表单时使用,Body内部存放的是JSON字符串。multipart/form-data 上传文件时经常使用。这种格式比较复杂,它是为了支持多文件上传混合表单数据而设计的一种特殊的格式
PUT 正儿八经的修改资源,put会覆盖效果,举个例子,你发一个子第一次发a第二次发b,那么只有b被留下了,a不见了,但是post,ab都在,所以这就是为什么post才是增加,而put是修改,而且还有一点需要注意,每次put需要put所有的参数,不然覆盖后有些没写的参数就是nil了
PATCH 它跟put对应,也是修改资源,但是它是可以修改部分资源的,就是参数可以不带起。
DELETE 删除资源
HEAD 类GET,就是返回的只有head的内容没有body的内容
OPTIONS 跨域请求的时候使用,用于获取这个url对应的相关的method这个是添加一个allow标签然后后面跟着 例如 allow:GET
TRACE 类似shell命令中的trace命令,获取资源在服务器中走动的各个流程的信息
CONNECT

http协议的真容

可能是最全的http协议总结


分块传送

当服务器向客户端传送动态资源的时候就会一块一块的传送,这个时候的传送就是一个thunk外加它的大小传给前端,分块传送需要在请求头增加一个特殊的键值对transfer-encoding: chunked

下面这部分就是消息体的显示,也就是将普通的string改成了这种形式。

可能是最全的http协议总结


持久连接

1.0之前如果不配置keep-Alive那么就是连接一次断一次,然后1.1一周 这个所谓的长链接就成默认的了。
KeepAlive Timeout参数和KeepAlive Requests参数限制单个连接持续时长和最多服务的请求次数。
如果timeout就是0,那么就OK了,直接退化为连接一次就断一次的行为了。非持久连接会在响应头部增加一个头信息Connection: Close通知客户端在接受完当前响应后连接需要立即关闭。所以说浏览器如果看到服务器发送给自己的信息里timeout不是0,那么它就会按照这个时间去长链接一会,如果看到了有head中有close,那么就直接关闭了。假如timeout服务器设置的过长,那么浏览器得到这个timeout的时候也不会认可的,因为它自己也有一个max的限制。

pipeline管线化

在之前没有管线化的时候,即使读一个响应一个,每次响应就会浪费一个ttl然后呢后来改了,就是使用了一个队列,把所有的连接请求都搞在一起,然后再读取他们。通过队列,就能得到先来的先处理,顺序也是一致的。这样就可以一次好多个才用了一个ttl。

无状态性

HTTP协议本身是无状态的,它并不会为不同的连接做区分,在http协议看来都是一样的,都是连接,所以我们要在应用层上做区别呀
也就是cookie-session机制了。

如果不使用https,如何保证http协议传输过程的安全性

主要由于http协议是一个可见的,不安全的协议,任何的内容都是暴露的,所以我们通常要使用https,http+tls证书的方式
所以这个问题的核心就是加密或者说是内容的不可见。

我们可以才用非对称加密,整个的过程是这样的,首先我们需要一对一对的公钥和私钥,然后为了节省动态生成这对的时间,我们搞一个公钥私钥的池子,也就是说我们一次生成一堆,然后每次用的时候去池子里取就好,定期更新池子即可。这样一动态生成了,安全性有了很大的保证,而来通过池子的效应,也提高了不少的效率。通过每次发送加密过的用户名和密码再加上公匙,然后使用例如hash表来查询到它的对应的私匙,这样就可以做到加密信息的效果了。

与之相对应的是对称加密,就是只有一个钥匙,这种方法效率高,解码的速度快,但是不够安全,因为你把私钥也发出来了,一般我们都是对称和非对称结合,也就是说让公钥去加密对称加密中的密匙,这样的化安全性有了保证,而且对称加密中的信息也少,这样公匙私匙加解密速度快了很多啊,然后对称加密中的钥匙再一解密,这样就是速度和安全并存了。

文件路径攻击

文件路径攻击就是 ..攻击,我们都知道大多数的系统中 .. 都是表示上一层,那么假如我们的服务器没有防范这个符号,然后黑客在访问我们的服务器的时候,输入了很多.. 举个例子把,假如我们有个路由是 xx/name 然后黑客给我们的信息是 xx/name/::/::/::/xxx如果是你要把某个路径的东西给用户,你代码中使用了 getpath("url") =》黑客的:getpath("../../../../")假如用户使用了这种URL你可能把根路径都给用户了。我们要做的就是检查来袭的URL看看是不是有.. 有..一律过滤掉

DNS 欺骗

那么好了,我作为一个黑客我将你电脑里或者手机里的dns信息给你更换了,本来你用的8.8.8.8,然后人家是正规的dns解析服务,然后都没问题,然后呢,我黑客,给你返回错误的IP,以此赚你的广告费,或者就是做一个李鬼的网站盗取个人信息。解决方法即使加速dns服务器的缓存时间,让它的缓存短一点。

外部http代理

外部http代理就是请求和服务器中间的中间服务器或者叫中间节点,如果这里做手脚很容易就倒霉了。

cookie

一般我们在cookie中存的都是session的session_id这些id跟session一一对应,因为cookie是存在用户本地的,所以很容易被盗走,我们可以使用https避免信息被套走,也可以服务器动态生成一些跟这个客户浏览器有关的东西,比如这样,本地上传一个时间给服务器,然后本地也记录,这样下次在传递过来session_id的时候把这个记录也发过来,一致的化就证明是正常的,否则就是假冒的。

  • Set-Cookie 这是cookie设置的时候的设置参数,意思就是只能被https访问,http不行

  • httpOnly 这个意思就是不能被js获取,只能由http浏览器使用。

这两个参数设置好也能做一定的防护。

CSRF

跨站请求伪造,意思就是给你一个URL,诱导你去做某件事,不如删了自己的文章 http://example.com/blog/123456/delete 假如又一个图片,然后它上面有这个URL,这个删除刚好是要看你的cookie中的session——id然后再去服务器验证身份的,刚好是你自己点击的,那么系统就判断你是真的想删除啊,然后就删了呗,这就是跨站请求伪造。

黑客在别的什么网站上伪造了一个POST表单,诱惑你去submit。如果只是普通的内嵌进HTML网页的表单,用户提交时会出现跨域问题。因为当前网站的域名和表单提交的目标域名不一致。但是如果通过iframe来内嵌表单,则可以绕过跨域的问题,而用户却完全没有任何觉察
<input type="hidden" name="csrf_token" value="xxxxxxxxxxxx">设置这个隐藏的条件就可以验证了,避免了csrf,它生成的时候就是你服务器给它的,然后你服务器记录好了,然后它提交表单的时候就会把这个信息再发过来你验证一下正确就OK了,如果不正常就是攻击。这个过程我说一下 首先比如你get打开一个页面的时候,这个时候服务器就会动态的渲染html,这个时候这个隐藏的inpu就应被渲染好了,同时这个信息传入数据库,然后你再提交表达的时候这不就是验证了吗。

XSS

跨域脚本,这个跟上面那个不同,上面那个的核心是诱骗你自己当黑客,就是用你的session_id然后用黑客的URL去做坏事,xss是某个黑客当自己是用户,它在里面植入了js代码,假设是输入信息的,那么它输入了js代码,如果你对js不作转义的话,就会对你攻击了,但是你转译一下就不会有问题了。

总结一下,csrf是黑客骗的是普通用户,通过你自己的钥匙去打开你家的门然后盗走东西,xss是黑客假装自己是客户,然后把病毒撒到服务器中。这是不同的。

跨域请求

服务器一般是禁止跨域请求的,因为如果这样的话,完全可以把某个用户的信息搞过来,然后你通过b站点获取他的个人信息。当然你或许会说我们仿造用户不就行了,这样就是csrf了,我们使用一个隐藏标签可以处理这个,所以一般服务器是禁止跨域的请求的,不让你使用他们的内部API,不过如果我们内部想访问怎么办呢?首先可以设置白名单,假如不设置白名单的话,我们也可以使用一个中转,比如你有三个域名服务 a.xx.com b.xx.com 然后统一用xx.com 做转发(可以使用nginx)。

  • jsonp

缺点:只能get 不能发送cookie

  • CORS
    cores使用ajax进行跨域请求,它什么都可以发,cookie也OK。服务器一般要设置如果是简单请求,Ajax直接请求服务器。

服务器:

会当成普通的请求直接返回内容,不同的是还会在响应头部添加几个重要的头部,其中最重要的头部是Access-Control-Allow-Origin: http://example.com  这里的就是允许的名单。可以设置多个,可以算白名单了,浏览器会根据这个数据去检查是否给让跨
值得说明的是就算请求的URL不是规定的,服务器也会发送,它不管这个,这个管理主要是浏览器,它规定信息是否让看,所以浏览器是很复杂的东西。浏览器的作用这里是不让脚本读到数据,所以跨域请求大多数都是ajax请求,如果是使用了一个get客户端去请求呢?
还能避免吗?答案是不能。只要这个客户端不能获取某个用户的cookie等信息就无所谓了。除非你主动提供(很多的内容分发就是这个原理去搞的嘛)

浏览器:

浏览器会在跨域的ajax上发送一个Origin参数,指明当前请求的发起站点来源。服务器根据Origin参数来决定是否授权。【简单请求】

简单请求就是头部很少很简单的GET/HEAD/POST请求

如果是复杂请求,那么浏览器会使用opinions方法去发送ajax的信息给服务器,服务器收到信息后同意了再发送给浏览器,浏览器再去请求服务器。所以复杂请求浪费了一个3次握手以及连接的机会,因为这个连接立马就断了不是长链接。



封面来自微博用户:重工组长于彦舒/侵删

欣赏一下原图:


以上是关于可能是最全的http协议总结的主要内容,如果未能解决你的问题,请参考以下文章

整理了Http协议get和post请求应该是全网最全了,收藏起来慢慢看

整理了Http协议get和post请求应该是全网最全了,收藏起来慢慢看

WPF这可能是全网最全的拖拽实现方法的总结

世上最全的RabbitMQ-总结

全网对 STP 生成树协议最全面最优质的总结,网络工程师收藏!

「HTTP协议」90%程序员都收藏的HTTP协议专题总结来啦