状态码

状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:

  • 1xx:指示信息–表示请求已接收,继续处理。
  • 2xx:成功–表示请求已被成功接收、理解、接受。
  • 3xx:重定向–要完成请求必须进行更进一步的操作。
  • 4xx:客户端错误–请求有语法错误或请求无法实现。
  • 5xx:服务器端错误–服务器未能实现合法的请求。
    平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500(分别表示什么请自行查找)。

301和302区别

301(Moved Permanently)

在请求的URL已被移除时使用。响应的Location首部中应该包含资源现在所处的URL。
301重定向是网页更改网址后对搜索引擎友好的最好方法,只要不是暂时搬移的情况,都建议使用301来做转址。比如说,我们将网页a的地址更改为b,采用301重定向,搜索引擎可以肯定网页a永久性改变网址,搜索引擎就会把网页b当做唯一有效目标,同时,网页a积累的页面权重将被传到网页b。(注:传递权重不同的搜索引擎不一样,Google会传递大部分权重,但不是百分之百权重)

当你想换域名的时候,就可以使用301,如之前的域名叫www.renfed.com,后来换了一个新域名fed.renren.com,希望用户访问老域名的时候能够自动跳转到新的域名,那么就可以使用nginx返回301:
server {
listen 80;
server_name www.renfed.com;
root /home/fed/wordpress;
return 301 https://fed.renren.com$request_uri;
}
浏览器收到301之后,就会自动跳转了。搜索引擎在爬的时候如果发现是301,在若干天之后它会把之前收录的网页的域名给换了。
还有一个场景,如果希望访问http的时候自动跳转到https也是可以用301,因为如果直接在浏览器地址栏输入域名然后按回车,前面没有带https,那么是默认的http协议,这个时候我们希望用户能够访问安全的https的,不要访问http的,所以要做一个重定向,也可以使用301,如:
server {
listen 80;
server_name fed.renren.com;

  1. if ($scheme != "https") {<br /> return 301 https://$host$request_uri;<br /> } <br />}

302(Found)

与301状态码类似,但是客户端应该使用Location首部给出的URL来临时定位资源,将来的请求仍应使用老的URL。
一般302重定向是在一个网站或网页在短时间内临时移到其它位置的情况下使用,这时候就是做临时性的跳转了。
但是302跟网址“劫持”有着莫大的关系。大部分搜索引擎在大部分情况下,当收到302重定向时,一般只要去抓取目标网址即可。但是有时候搜索引擎(以Google为例)并不能总是抓取目标网址,比如说a网址很短,但是它做了302重定向到b网址,而b网址是一个很长的乱七八糟的URL网址,这时候Google很有可能仍显示网址a,这时候就造成了网址劫持的可能性。如果一个居心叵测的人将一个网址a通过302重定向到你的网址b,而Google搜索结果仍然是A,这种情况就是网址劫持。同时,还容易导致网站被降权,所以尽量不用。

很多短链接跳转长链接就是使用的302,如下图所示:

304 Not Modified

如果客户端发送了一个带条件的GET请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器返回304状态码。304响应不包含消息体,因此以消息头后的第一个空行结尾。
在一条HTTP GET请求中,大致是如下的一个过程
状态码 - 图1
在查看本地副本是否过期时,通过检查Cache-Control或者Expires首部即可获知。HTTP通过Cache-Control首部和Expires首部向每个文档附加了一个“过期日期”,在缓存文档过期之前,缓存可以以任何频率使用这些副本,而无需与服务器联系。
Expires首部是HTTP/1.0定义的字段,指定的是一个绝对的过期日期。而Cache-Control是HTTP/1.1定义的字段,max-age值定义了文档的最大使用值,是相对时间。因为绝对时间需要依赖于计算机时钟的正确设置,容易存在误差。所以,我们更倾向于使用比较新的Cache-Control首部。当同时存在Expires和Cache-Control:max-age字段时,Cache-Control:max-age字段会覆盖Expires字段。同时存在这两个字段还有一个好处,就是可以兼容HTTP/1.0。
本地缓存过期了并不意味着它和原始服务器上目前处于活跃状态的文档有实际的区别,这时候缓存需要询问原始服务器文档是否发生了改变,跟原始服务器做一次 新鲜度校验
HTTP条件方法可以高效地实现再验证。通过If-Modified-Since或者If-None-Match首部来校验。
If-Modified-Since:Date再验证:If-Modified-Since首部可以和Last-Modified服务器响应首部配合工作。原始服务器会将最后的修改日期附加到所提供的文档上去。
If-None-Match: 实体标签再验证:有些文档可能被被周期性的重写、有些文档可能被修改了但所做修改不重要等等这类情况下,使用最后修改日期进行再验证是不够的,这时候HTTP允许用户对被称为实体标签ETag的“版本标识符”进行比较。
实体标签和最近修改日期都是缓存验证器,如果服务器回送了一个实体标签,HTTP/1.1客户端就必须使用实体标签验证器。如果只返回了一个Last-Modified值,客户端就可以使用If-Modified-Since验证。如果实体标签和最后修改日期都提供了,客户端就应该使用这两种再验证方案,这样HTTP/1.0和HTTP/1.1缓存就都可以正确响应了。如果HTTP/1.1服务器收到的请求既带有If-Modified-Since,又带有ETag条件首部,那么需要这两个条件都满足时,才能返回304 Not Modified响应。

参考
https://segmentfault.com/a/1190000006879700
https://harttle.land/2015/08/15/http-status-code.html#header-11
https://aotu.io/notes/2016/01/28/3xx-of-http-status/index.html
https://github.com/xiangxingchen/blog/issues/14