http状态码,及302和301区别,200 和304 区别

HTTP 状态码

当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。
HTTP 状态码的英文为 HTTP Status Code
下面是常见的 HTTP 状态码:

  • 101 - 切换协议
  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 302 - 临时重定向
  • 304 - 未修改
  • 403 - Forbidden(禁止访问),服务器拒绝请求
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误
  • 502 - Bad Gateway(坏的网关),一般是网关服务器请求后端服务时,后端服务没有按照http协议正确返回结果。
  • 503 - Service Unavailable(服务当前不可用),可能因为超载或停机维护。
  • 504 - Gateway Timeout(网关超时),一般是网关服务器请求后端服务时,后端服务没有在特定的时间内完成服务。

    HTTP 状态码分类

    HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:信息响应(100–199)成功响应(200–299)重定向(300–399)客户端错误(400–499)服务器错误 (500–599)
分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误
301和302的区别:
  • 301 Moved Permanently 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
  • 302 Found 请求的资源现在临时从不同的URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-ControlExpires中进行了指定的情况下,这个响应才是可缓存的。

字面上的区别就是301是永久重定向,而302是临时重定向。 当然,他们之间也是有共同点的,就是用户都可以看到url替换为了一个新的,然后发出请求。

  • 301适合永久重定向
      301比较常用的场景是使用域名跳转。
      比如,我们访问 http://www.baidu.com 会跳转到 https://www.baidu.com,发送请求之后,就会返回301状态码,然后返回一个location,提示新的地址,浏览器就会拿着这个新的地址去访问。

    注意: 301请求是可以缓存的, 即通过看status code,可以发现后面写着from cache。
    或者你把你的网页的名称从php修改为了html,这个过程中,也会发生永久重定向。

  • 302用来做临时跳转
    比如未登陆的用户访问用户中心重定向到登录页面
    访问404页面会重新定向到首页。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    ##niginx 301/302配置

    ##rewrite后面接上permenent就代表301跳

    //把来自veryyoung.me的请求301跳到 www.veryyoung.me
    if ($host != 'veryyoung.me') {
    rewrite ^/(.*)$ http://www.veryyoung.me/$1 permanent;
    }


    ##接上redirect就代表302跳

    //把来自veryyoung.me的请求302跳到 www.veryyoung.me
    if ($host != 'veryyoung.me') {
    rewrite ^/(.*)$ http://www.veryyoung.me/$1 redirect;
    }
  • 使用时机
    302重定向只是暂时的重定向,搜索引擎会抓取新的内容而保留旧的地址,因为服务器返回302,所以,搜索搜索引擎认为新的网址是暂时的。
    而301重定向是永久的重定向,搜索引擎在抓取新的内容的同时也将旧的网址替换为了重定向之后的网址。
    200 OK (from memory/disk cache)和304 Not Modified

1、 200 OK (from memory/disk cache)

这种缓存方式已经很普遍,大部分网站的静态文件都采用了,200 OK (from memory cache)或者200 OK (from disk cache)都是直接读取客户端的缓存,无需再请求服务器。一般是在Apache或者Nginx里设置,比如Nginx配置里会有类似这样的配置:

1
2
3
4
5
6
7
8
9

location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires      30d;
}
location ~ .*\.(js|css)?$
{
expires      12h;
}

这样就可以给静态文件缓存了,在有效期内,浏览器会直接读取客户端的缓存,而不用再请求服务器,除非用户清除了缓存或者使用Ctrl+F5强制刷新了页面。

比如上图,是已经缓存过了的,至于有些是200 OK (from memory cache)有些会是200 OK (from disk cache)都差不多,只是从客户端取的位置不一样而已。除了给静态文件做200 OK (from cache)缓存外,其实我们也可以给某些页面做,比如一些不经常改变内容的ajax页面。

2、 304 Not Modified

304缓存和上面最大的区别是浏览器需要向服务器询问一次,如果服务器端认为没有内容更新,直接返回304状态码,无需返回body内容,浏览器就会直接取缓存内容输出,这样省掉了没必要的数据传输,也就提升了访问速度。

要实现304缓存,我们需要在浏览器首次访问时返回过期时间等header,比如如下PHP代码:

1
2
3

$time=86400; //单位秒
header('Cache-Control:max-age=' . $time); header("Expires: " . gmdate("D, d M Y H:i:s", time() + $time) . " GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");

上面的代码就告诉了浏览器缓存时间,下次浏览器再访问该页面的时候会带上名叫IF_MODIFIED_SINCE的请求头来访问,这时候我们可以用PHP变量:$_SERVER['HTTP_IF_MODIFIED_SINCE']来获取浏览器记录的缓存时间,如果没有内容更新,我们直接返回304状态码即可,如果有更新直接输出新内容,并返回新的过期时间给浏览器。大概的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$time = 86400;
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])){
$is_update=0;//判断是否有更新
if($c_time > time()){
header('Cache-Control:max-age='.$time);
header("Expires: " . gmdate("D, d M Y H:i:s",time()+$time)." GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header('HTTP/1.1 304 Not Modified');
exit();
}
}
header('Cache-Control:max-age=' . $time);
header("Expires: " . gmdate("D, d M Y H:i:s", time() + $time) . " GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");

具体使用还需要考虑一些其它问题,本站就已经在很多页面使用了304缓存功能,返回状态如下图: