碎碎念:发现自己每次写博客前面都写的比较欢快,写着写着问题一多了我就烦了,害。
4/22:今天第一次面试,真的特别紧张,自己表达能力太差,说到底还是不熟吧,脑子一片空白,能想到啥说啥。其实我应该说更多的,但是准备的不充分,面试完才发现面试官是想了解一下我的广度。面试完之后颓废了5个小时,不敢颓废下去了,现在重新振作。好好做好自己能做的事,勇敢一点,加油,奥利给!(为什么我写博客跟写日记一样的?)
HTTP是啥?
HyperText Transfer Protocol。超文本传输协议,我们把这个名词砍开看:
-
超文本
什么是超文本呀?我们先说文本,文本总知道吧,就是字符和文字。其实图片,视频,压缩包啥的HTTP都当他是文本。那么什么是超文本呢?超越普通文字,是文字、图片、视频等的混合体(也就是我们的HTML啦),还有超链接,可以从一个超文本跳转到另一个超文本。
HTML是很常见的超文本,他看起来只是纯文本对吧,但是它里面又用很多标签定义了图片,视频,超链接啥的。然后浏览器一解释,嘿!一个网页就出来了!
-
传输
传输就是,把东西从一个地方传到另一个地方。但要注意的是,HTTP中的传输还有其他的细节:
-
双向传输
当我们想要访问某个网站A的时候,浏览器就会帮我们发送请求到该网站A的服务器,然后服务器返回数据文件给浏览器,浏览器就帮我们渲染这些数据文件,呈现我们所看到的网页。
也就是说呢,浏览器可以向服务器发送请求,服务器可以向浏览器返回应答。这就是双向传输。
-
传输的过程中允许有中转
就像我们传纸条一样,从第一排的小A传到最后一排的小E,中间要经过好几个人(小B小C小D)。但是这些人(中间人)要遵守HTTP协议呀!你们不能把我的纸条偷偷藏起来,也不能在偷偷上面写什么猥琐的东西...当然如果HTTP符合规范的话,写东西还是可以的。
-
-
协议
这个就很好理解吧,协议的协要求有两个人一起参与,然后协议的议要求通过双方的交谈来达成一种规范。
总的来说,HTTP超文本传输协议就是:一种计算机之间的协议,他规定了在两点之间传输超文本数据的规范。
为什么说是两点,而不是服务端到和客户端之间呢?因为这个协议也可以用在服务端和服务端之间呀~
关于HTTP常见的状态码?
状态码是啥捏?浏览器给服务器发送请求之后,服务器会返回一个状态码来响应浏览器的请求。换句话说,只要请求到了服务器,服务器处理之后就会返回给你一个状态码。
好,那我们就来看看状态码。
这个其实还挺难记住的,但是我们可以挑重点来记,然后遇到的时候多看几次。我参考的那篇文章讲的不是很详细,刚好最近又复习过状态码,所以大部分都用自己的笔记来阐述啦。
| 分类 | 分类描述 |
|---|---|
| 1** | 提示信息,协议还在处理。 |
| 2** | 成功,操作被成功接收并处理。 |
| 3** | 重定向,资源位置变动,要重新发送请求。 |
| 4** | 客户端错误,请求包含语法错误或无法完成请求。 |
| 5** | 服务器错误,服务器在处理请求的过程中发生了错误。 |
1**
100 Continue
参考文章:《HTTP 100 Continue 状态码处理》
表明目前为止的所有内容都是正常的,其实他的应用场景主要是:客户端发送一个100 Continue Expect 首部,告诉服务器说:我们将要发送一些数据给要发送给你,但发送之前想查看一下服务器是否会接受这个数据。
其实发送了100 Continue Expect首部的客户端也不要一直等着服务器给你100 Continue响应之后才发送数据,规定一个超时时间,如果服务端还没有响应,客户端应该直接将数据发送出去,这时候服务端看到数据来了就不会给你返回100了,会直接返回这个正式请求的响应码。
101 Switching Protocols
表示服务器正在根据你之前的请求中,那个Upgrade字段的内容,去切换协议。假如我们要求客户端升级协议为WebSocket协议,那么他的返回报文应该是如下形式:
HTTP/1.1 101 Switching Protocols
//使用websocket协议
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
服务端返回报文的同时,会返回101状态码。
2**
200 OK
每次看到就开心到想跳起来的状态码,成功的意思,表示一切正常。只要不是HEAD请求,服务器返回的响应头都会有body数据。
但是!这里说成功不是说我们请求的就一定对了,就像我们昨天说的那个cors,有时候虽然返回的是200但是并不一定是说这次请求就成功了,他只是说服务器处理成功了。所以有时候也不要高兴得太早...
204 No Content
成功,但是没有返回任何内容,响应头没有body数据。我们使用cors的非简单请求的时候,预检就会返回这个状态码。
服务器:请求成功啦,但是我没啥东西给你哦。
一般在从客户端往服务器发送信息,而不需要新信息的时候使用。比如说cors预检,只需要服务器告诉我现在允不允许跨域,而不需要更新我们的页面,如果允许跨域,我们再发送正式请求去请求资源然后更新页面。
206 Partial Content
应用于HTTP分块下载或断点续传,表示响应返回的body数据不是资源的全部,而是其中的一部分。但是也是处理成功的状态。响应报文中包含Content-Range指定范围的内容,例如:
"content-range": byts 5001-10000
//表示本次返回的范围是5001-10000字节
服务器:你只想要一部分?好吧,那我就只给你这一部分资源。
(类似于FlashGet或者迅雷这类的HTTP下载工具,都是使用此类响应实现断点续传,或者将一个大文档分解为多个下载段同时下载。)
不太常见的一些
-
201 Created:成功请求并且并且服务器创建了新的资源,资源的URI已经随Location 头信息返回。如果无法及时建立就会返回 '202 Accepted'。
-
202 Accepted:表示请求已经接受了但是服务器还没有来得及处理。
-
205 Reset Content:没有返回任何内容,但是要求客户端重置内容。表示:ok,服务器已经处理成功了,浏览器你要重新刷新页面哦。
他主要是被用于接受用户输入后,立即重置表单,以便用户能够愉快地开始另一次输入。
总结
个人感觉2**这一块还是挺好记的哈,反正就是成功了嘛。
- 200(OK)是最常见的成功
- 如果是204(No Content),205(Reset Content)就表示服务器没返回数据,204不会刷新页面,但是205会要你刷新页面。206(Partial Content)表示返回部分数据。
- 如果服务器要创建新的资源就用201( Created,创建成功),202(Accepted,还没创建)。
3**
301 Moved Permanently
表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
服务器:诶!我把这个资源搬走啦,他以后都会住在那里,你要是要找他就去Location指定的那个地方找他吧。以后都要去那里找他哦。
为什么要做这个重定向?重定向对用户和搜索引擎来说都是很重要滴,资源的位置改变之后,如果使用了301重定向,用户、搜索引擎找到旧地址的时候就不会直接显示404错误页面。浏览器会根据返回的新地址,自动发送请求去访问新版本的页面。
302 Moved Permanently
表示临时重定向,说明请求的资源还在,但暂时需要用另一个URL来访问。
服务器:我把这个资源搬走啦,但是他也不一定长住在那里,所以你以后还是来这里找吧,到时候我再告诉你他在哪里。
301和302都会在响应头里使用字段Location告诉浏览器要跳转到那里,这个时候请求方法是不限制的,但是实际上客户端自己会用GET方法访问。
303 See Other
和302是一个意思啦,但是303要求一定要用GET方法去访问新的地址。
比如我们使用POST方法访问服务端,但服务端的处理结果是"希望客户端能以GET方法重定向到另一个地址"。
(其实在使用301,302,303的时候后几乎所有的浏览器都会自动把POST变成GET,然后删除请求报文里面的主体,再次请求新地址。)
304 Not Modified
官方的解释是说:客户端发送附带条件的请求的时候,服务端允许访问资源但是未满足条件。
看起来是不是怪怪的,再详细解释一下。
服务端有个ETag(实体标记)的字段,我们可以看作是一个资源的标记,当资源更新后Etag也会更新。然后我们请求时一般的附加条件包括:
-
if-Match传递一个ETag值,表示只请求带有指定标记(ETag)的资源。表示:我们请求一个资源,条件是一定要有这个标记。如果服务端那边没有,就会返回412状态码(后面会说)。 -
if-Modified-Since传递一个时间,它会把浏览器端缓存的最后更新时间发过去,如果和服务端的资源更新时间一致就表示资源没发生变化。返回304状态码。 -
if-none-Match和if-Match相反。传递一个ETag值,只有ETag和那边的资源不一样的时候才会处理这个请求,可以用来获取新资源,和if-Modified-Since有点像。 -
If-Range传递一个ETag值,表示我要请求一个资源,如果这个标记和你那边的资源标记一样,你就帮我返回资源。如果标记不一样,那你也帮我返回对应的资源。 -
if-Unmodified-Since传递一个时间,只有在资源的更新日期在此之前(没有发生更新)的情况下才能处理。
所以说,如果说不满足条件上面的条件,有可能是if-Modified-Since不满足,也就是说资源没有更新。所以这时候服务器不会返回任何资源,会让我们拿缓存里面的资源。
服务器:我这边的资源也没有更新哦,我就不发给你啦,你还是用你缓存的吧~
这个状态码本来不具有跳转的含义,但是硬扯的话也能解释成:资源未修改,重定向到已存在的缓冲文件。
307 Temporary Redirect
遵循浏览器标准,重定向的时候不会从POST变成GET,原来用什么方法请求的就用什么方法重定向,但是处理响应的时候每种浏览器都可能出现不同的情况。
不太常见的一些
-
300 Multiple Choices
多种选择。客户来请求的文档可以在多个位置找到,这些位置已经在返回的文档内列出。用户代理或用户应该选择其中的一个。由于没有如何进行选择的标准方法,这个状态码极少使用。
-
305 Use Proxy
使用代理。所请求的资源必须通过代理访问。有时候表示你需要内个V什么什么...
总结
总结一下,其实3开头的就是重定向对吧。
- 301(Moved Permanently),302(Found)都是直接告诉你要去访问其他地址,然后如果是永久的地址就用301,暂时的就用302。要注意的是虽然规范不允许,但是浏览器重定向的时候都喜欢把请求方法改成GET方法,然后就出来了303( See Other),说清楚重定向一定要用GET方法,然后307( Temporary Redirect)又跑出来了,说我不改你的,原来用的什么方法重定向的时候就用什么方法。
- 然后就是针对资源的几个。300就是这个地址对应了几个资源啊,你挑一个吧。304(Not Modified)就是说,资源没更新呀,不给你啦。
- 最后一个305(Use Proxy),要你先去找代理。
ok!来看4**
4**
4**是最让我头疼的几个,反正都是我的错呜呜。
400 Bad Request
表示请求中存在语法错误,错误发生的时候需要修改我们的请求内容。那具体是啥语法错误呢?对不起,不告诉你,自己摸索吧~但是一般来说响应报文里面都会有一些提示的,比如说:
"哎呀,这个多加的是什么请求头,我不能接受呀。"
"哎呀,地址好像不太对哦。"
"哎呀,你的请求方法不对呀"。。
401 Unauthorized
请求要求用户的身份认证,对于需要登录的网页,服务器可能返回此响应。他和403有点像,但是他还能进行身份认证,403就直接说你没有权限访问了。
服务器:"你要先进行身份认证哦,如果你之前已经认证过了,那就是认证失败啦。"
403 Forbidden
表示服务端理解你的请求(也就是我们的请求没有出错),但是拒绝你(听起来有点惨)。而且服务端没有必要给你拒绝的详细理由(好霸道的样子),但是如果想说明理由也可以在响应的主体部分说明。
服务器:"我理解你,但是我拒绝你,提供身份验证也没用,我还可以不给理由。"
具体场景有:未获得系统的访问授权,访问权限出现问题(从未授权的IP地址试图访问),也有可能是身份验证的时候写错了密码。
404 Not Found
表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。许多网站都会利用这个代码来自定义404页面的外观。
服务器:"找不到这个页面哇。"
除此之外,也可以在服务器拒绝请求而且不想说明理由的时候使用。
4开头的状态码有很多,但是,后面都是不怎么常用的,但是,还是了解一下吧。如果现在不看也不知道什么时候再捡起来看了。
不太常见的一些
-
405 Method Not Allowed
表示你的请求方法被服务器禁用且无法使用。但是有两个强制性方法,
GET和HEAD,绝不能被禁用,不应返回该错误代码。服务器:"这个请求的话,不能用这个方法哦。"
-
407 Proxy Authentication Required
请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权。
服务器:"去找代理给你身份验证哦~"
-
408 Request Time-out
表示服务器想要关闭掉没有在使用的连接,一些服务器会在空闲连接上发送此信息。可能的场景是客户端没有在服务器预备等待的时间内完成一个请求的发送,当然客户端也可以随时再次提交这一请求。还有一些服务器会直接关闭连接而不发送这类消息。
服务器:"不等你啦,你不用连接的话我就把你关掉啦。"
-
409 Conflict
一般发生在
put请求响应中,表示请求与服务器端目标资源的当前状态相冲突。说有可能我们用put上传文件的版本比服务器上的要旧,导致版本冲突,这时候就返回409。 -
410 Gone
如果用户访问的网页被永久删除,服务器就会返回410代码。410实际上和404有点相似,在服务器不确定这个情况是不是永久的情况下,应该使用404状态码。
410响应的目的主要是通知用户这个网页已经不能再使用,并且希望所有指向这个网页的链接也被删除。也可以设置301和302来重定向。
-
411 Length Required
表示由于缺少
Content-Length首部字段,服务器拒绝客户端的请求。要注意,当我们使用分块模式传输数据的时候,
Content-Length首部是不存在的,但是需要在每一个分块的开始添加该分块的长度。 -
412 Precondition Failed
意味着对于目标资源的访问请求被拒绝。一般是在首部字段
If-Match、If-None-Match规定的先决条件不成立的情况下。If-Match就是我们之前说的那个,只有当:我们请求的资源携带的标记,和服务端那边对应的资源的标记,是一样的,才会返回。如果不一样,服务端就返回412。If-None-Match的情况就相反啦。 -
413 Payload Too Large
请求主体的大小超过了服务器愿意或有能力处理的限度,服务器可能会关闭连接以防止客户端继续发送该请求。
-
414 URI Too Long
表示客户端所请求的URI超过了服务器允许的范围。比如我们把POST请求当作GET请求时。
-
415 Unsupported Media Type
官方解释:是一种HTTP协议的错误状态代码,表示服务器由于不支持媒体的有效载荷的格式,从而拒绝接受客户端的请求。
格式问题的出现有可能源于客户端在
Content-Type或Content-Encoding首部中指定的格式,也可能源于直接对负载数据进行检测的结果。有效载荷是啥呢?参考文章:《http请求中的payload》
payload,翻译过来是有效载荷。可以理解为一系列信息中最为关键的信息。
比如说一个ajax请求有以下的内容:
{ status: 200, hasError: false, data: { userId: 1, name: 'undefined' } }这里面的data就是最重要的信息,也就是payload。
通常在传输数据的时候,会把数据分批传输,然后在数据的头尾加上一些信息,比如数据长度什么的,这样子就会形成数据包。其中的原始数据就是payload有效载荷。
看了一下别的博客,其中有一篇博客在数据传输的格式错误的时候遇到了这样的状态码。《http请求415错误Unsupported Media Type》,是在
content-type出现错误的时候出现的问题。 -
416 Range Not Satisfiable
最常见的情况是所请求的数据区间不在文件范围之内,也就是说
Range首部的值没有意义。 -
417 Expectation Failed
官方解释:状态码表示客户端错误,意味着服务器无法满足
Expect请求消息头中的期望条件。好笼统哦,看不懂。于是百度一下~参考文章《关于HTTP请求返回417 “Expectation Failed”》
这个和100是相对的,场景是:客户端发请求体之前先试探一下服务器,看服务器接不接受我们的数据呀,再决定要不要发数据。如果服务器返回100,就表示可以接受,我们就把数据用post发送给服务器。如果服务器不同意呢?就返回417啦。
-
418 I'm a teapot
官方解释:表示服务器拒绝冲泡咖啡,因为它是个茶壶。该错误是超文本咖啡壶控制协议的参考,和 1998 年愚人节的玩笑。
什么咖啡?什么茶壶??听起来好像有点味道,但是我还是不懂啊。行吧,我再百度。百度了一下好像也没人遇到这个状态码,有些是在使用npm的时候遇到了这个问题,都是在设置registry的时候直接用的http。没有使用https安全认证。
然后继续了解了一下,参考:《HTTP 418 I'm A Teapot - Just A Joke, Or Something More?》
了解到编写这个规范的目的,是为了指出过度扩展HTTP的风险。当我们能够使用更加通用的方案去实现功能的时候,不去要使用特定的(也就是拓展的)方法。
-
422 Unprocessable Entity
请求格式正确,但是由于含有语义错误,无法响应。参考了这一篇博客《Laravel+Vue 前后端分离》,说是把用户输入的密码和确认密码发送到后端之后,如果密码长度不符合后端的要求,或者是密码和确认密码不一致的时候报了这样的错误。
-
425 Too Early
服务器不愿意冒风险来处理该请求,原因是处理该请求可能会被"重放",从而造成潜在的重放攻击。也是一个很少出现的状态码,百度都搜不到。但是仔细想想如果我是攻击者我也不可能写一个:"我遇到了425错误,求大佬帮忙解决!!"这样的博客吧...
那就说一下重放攻击吧,最近看到的攻击好多,打算开几篇博客专门了解攻击。
重放攻击就是:第三方捕获了双方的历史通信报文,在合适的时间重新发送一次或多次不等。
比如说:A向B认证自己,然后B要A提供账户和密码。但是嘞C这时候偷听到他们的通信,然后记下了A的账号密码。等到A和B完成通信之后,C找到B,假装自己是A。然后B找C要账号密码,C就把偷偷拿到的A的账号密码给他。这时候B就以为C是A了。
-
426 Upgrade Required
服务器不想处理当前协议发送的请求,但是你可以把协议升级之后再去请求服务器。服务器会在响应中使用
Upgrade首部来指定要求的协议。另一种解释是说客户端应当把协议切换到TLS/1.0。 -
428 Precondition Required
表示服务器端要求发送条件请求,一般是说少了必要的条件首部,如没有
If-Match或If-None-Match。记住是少了哦!如果是不匹配应该是返回412滴。 -
429 Too Many Requests
表示在一定的时间内发送了太多的请求,超出了频次限制。服务端响应的时候,可以提供一个
Retry-After首部来提示用户需要等待多长时间之后再发送新的请求。 -
431 Request Header Fields Too Large
请求头太大了,所以拒绝请求。我们可以缩减首部字段的提及之后再发送请求。
-
451 Unavailable For Legal Reasons
表示服务器由于法律原因,无法提供客户端请求的资源,例如可能会导致法律诉讼的页面。当用户请求访问某个经政府审核等查核方法后认定不合法的来源时,就会显示这个错误代码。
总结
ok,来总结一下超多的4**:
-
400( Bad Request),笼统的错误,没啥好说的。
-
跟访问权限有关的:
401(Unauthorized)要身份认证,407( Proxy Authentication Required)是要去找代理认证身份;403(Forbidden)就是直接说你没权限访问,404(Not Found)就是找不到,也有可能是想拒绝你又不想给理由。和404有点像的是410(Gone),但是410是确定永久删除。
-
跟请求头有关的:
- 与请求的首部字段有关的是:411(Length Required),缺少
Content-Length首部字段;412 (Precondition Failed),首部字段的条件不成立,和他有点像的是428(Precondition Required),但是428是说你少了字段而不是不成立;416(Range Not Satisfiable),Range首部的值没有意义;417(Expectation Failed),无法满足Expect请求消息头中的期望条件。 - 有几个是因为你发的信息太大了,413(Payload Too Large)是因为请求主体的大小太大;414(URI Too Long)表示客户端所请求的URI超过了服务器允许的范围;429(Too Many Requests)表示在一定时间内发送了太多的请求;431(Request Header Fields Too Large)表示请求头太大了。
- 与请求的首部字段有关的是:411(Length Required),缺少
-
你的请求报文中有些东西是不支持的:
405(Method Not Allowed),表示你的请求方法被服务器禁用;415(Unsupported Media Type)是说有效载荷的格式不支持;418(I'm a teapot)是说不要乱扩展HTTP协议;426(Upgrade Required)是说你这个协议他不能处理,要你换个协议;
-
跟安全有关的:
425(Too Early)是说你这请求可能会导致重放攻击;451(Unavailable For Legal Reasons)是说由于违法不给看。
-
其他的几个:
408(Request Time-out)表示你不发东西就关闭连接;409 (Conflict)表示你上传的东西比我这里的还旧;422(Unprocessable Entity)是说语义有错误,后端验证不通过。
5**
5**虽然也头疼,但是可以甩锅给后端还是有点开心的哈哈哈哈哈,每次看到5**都很愉快的跑去找后端:"嘿嘿大哥,你又有事做了"。
500 Internal Server Error
也是一个笼统的代码,就是说服务端错误了,至于是什么错误他也不告诉你(反正你也不一定能看懂)。
501 Not Implemented
表示请求的方法不被服务器支持,因此无法被处理。服务器必须支持的方法(即不会返回这个状态码的方法)只有GET和HEAD。
他和405的区别是,405实现了这个请求方法,但是只是在特定的请求中不支持。
502 Bad Gateway
502的意思就是代理服务器从上游服务器接收到了无效的响应。
解释一下网关和代理服务器:
出现502的原因有可能是浏览器开了代理;有可能是服务器内压力太大,内存耗尽(这种情况强制刷新一下可能就好了);有可能是防火墙阻止了请求;有可能是DNS还没有更新过来(可能网站比较新,这时候要刷新一下DNS缓存)。我一般出现这个错误都是因为后端没开服务器。
503 Service Unavailable
表示服务器暂时无法响应服务器,通常造成这种情况的原因是由于服务器停机维护或者已超载。
服务器:"太忙啦,等下再来吧!"
不太常用的一些
-
504 Gateway Timeout
表示网关或代理服务器无法在规定的时间内获得想要的响应。有可能是服务器响应太慢导致nginx超时。具体的例子看这里《nginx设置连接超时解决504 gateway timeout》,比如说我们用nginx做反向代理,默认请求是有一个60秒的超时,如果http请求超过了60秒再返回,连接就会被nginx中断,前端就会得到504的错误:gateway time-out。
-
505 HTTP Version Not Supported
表示服务器不支持请求所使用的HTTP版本。emm..没啥好说的,在老版本浏览器里面可能会用比较老的HTTP版本。
-
511 Network Authentication Required
指示客户端需要进行身份验证才能获得网络访问权限。这种状态其实不是由服务器生成的,而是通过拦截代理来控制对网络的访问。参考文章:《Http_4个新的http状态码:428、429、431、511》
有时候我们想连接一些公共WIFI,不是会让我们接受一些协议,或者是登陆之后才能使用吗。这是通过拦截HTTP流量来实现的。"拦截"的时候会有一些副作用,例如:
- 如果我们在登录WIFI之前访问了某个网站,然后网络设备会拦截首个请求让你去登录。然后这些设备往往也会有自己的网络图标。我们登陆之后会发现,有一段时间之内我们访问的网站图标一直是WIFI登录网站的图标。
- 如果我们使用HTTP请求查找文档,突然被拦截了然后网络响应给你一个登录页,这会导致我们的客户端解析错误。
而511状态码的提出就是为了解决这个问题。因此,如果你正在编写HTTP的客户端,你最好还是检查一下511状态码,确认一下是不是要认证后才能访问。
总结
总结一下5开头的
- 500(Internal Server Error)是一个笼统的错误,没啥好说的。
- 502(Bad Gateway)和504(Service Unavailable)是网关和代理服务器返回的错误,502是说收到了无效的响应,504是说无法在规定时间内获得响应。
- 501(Gateway Time-out)和505(HTTP Version not supported)是因为服务器不支持,501是不支持请求方法,505是不支持协议版本。
- 503(Service Unavailable)是服务器太忙,511(Network Authentication Required)是需要身份认证才能上网。