一、概述

重定向常常和请求转发放在一起讨论(前者是两次不相关的请求,后者是一次请求服务器端转发),然而本文并不讨论两者的区别,而是HTTP 1.0规范和HTTP 1.1规范中关于重定向的区别,以及实际使用中的情况。

重定向实际使用是一个响应码(301或302或303或307)和一个响应头location,当浏览器收到响应的时候check响应码是3xx,则会取出响应头中location对应的url(重定向中url的编码问题,请参看点击打开链接),然后将该url替换浏览器地址栏并发起另一次HTTP事务。

关于301、302、303、307的区别,找不到好的文章,因此打算直撸HTTP 1.0规范和HTTP 1.1规范,结合一些实际的案例和tomcat实现,来说清楚这几个状态码的差异。

1. 百度https重定向

如下图所示,原请求访问的是http://www.baidu.com,然后返回302和location=https://www.baidu.com,从http转到https。不过关于响应行中302状态码的描述存在争议,在下文中会详细讨论。

2. tomcat重定向源码

二、详细

http 1.0规范中有2个重定向——301和302,在http 1.1规范中存在4个重定向——301、302、303和307,其中302是值得讨论讨论的。

1. http 1.0

301

301状态码在HTTP 1.0和HTTP 1.1规范中均代表永久重定向,对于资源请求,原来的url和响应头中location的url而言,资源应该对应location中的url。对于post请求的重定向,还是需要用户确认之后才能重定向,并且应该以post方法发出重定向请求。

关于post请求重定向用户确认的问题,实际上浏览器都没有实现;而且post请求的重定向应该发起post请求,这里浏览器也并不一定遵守,所以说HTTP规范的实现并未严格按照HTTP规范的语义。

在301中资源对应的路径修改为location的url,在SEO中并未出现问题,但是在302中就出现了302劫持问题,请往下看。

302

在http 1.0规范中,302表示临时重定向,location中的地址不应该被认为是资源路径,在后续的请求中应该继续使用原地址。

规范:原请求是post,则不能自动进行重定向,需要用户确认才能重定向;原请求是get,可以自动重定向;

实现:浏览器和服务器的实现并没有严格遵守HTTP中302的规范,服务器不加遵守的返回302,浏览器即便原请求是post也会自动重定向,导致规范和实现出现了二义性,由此衍生了一些问题,譬如302劫持,因此在HTTP 1.1中将302的规范细化成了303和307,希望以此来消除二义性。

补充:302劫持——A站通过重定向到B站的资源xxoo,A站实际上什么都没做但是有一个比较友好的域名,web资源xxoo存在B站并由B站提供,但是B站的域名不那么友好,因此对搜索引擎而言,可能会保存A站的地址对应xxoo资源而不是B站,这就意味着B站出了资源版权、带宽、服务器的钱,但是用户通过搜索引擎搜索xxoo资源的时候出来的是A站,A站什么都没做却被索搜引擎广而告之用户,B站做了一切却不被用户知道,价值被A站窃取了。

If the 302 status code is received in response to a request using the POST method, the user agent must not automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.

Note: When automatically redirecting a POST request after receiving a 302 status code, some existing user agents will erroneously change it into a GET request.

2. http 1.1

301

和http 1.0规范中保持一致,注意资源对应的路径应该是location中返回的url,而不再是原请求地址。

302

在HTTP 1.1中,实际上302是不再推荐使用的,只是为了兼容而作保留。规范中再次重申只有当原请求是GET or HEAD方式的时候才能自动的重定向,为了消除HTTP 1.0中302的二义性,在HTTP 1.1中引入了303和307来细化HTTP 1.0中302的语义。

If the 302 status code is received in response to a request other than GET or HEAD , the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user , since this might change the conditions under which the request was issued.

Note : RFC1945 and RFC2068 specify that the client is not allowed to change the method on the redirected request. However, most existing user agent implementations treat 302 as if it were a 303 response, performing a GET on the Location field-value regardless of the original request method . The status codes 303 and 307 hava been added for servers that wish to make unambiguously clear which kind of reaction is expected of the client.

303

在HTTP 1.0的时候,302的规范是原请求是post不可以自动重定向,但是服务器和浏览器的实现是运行重定向。

把HTTP 1.0规范中302的规范和实现拆分开,分别赋予HTTP 1.1中303和307,因此在HTTP 1.1中,303继承了HTTP 1.0中302的实现(即原请求是post,也允许自动进行重定向,结果是无论原请求是get还是post,都可以自动进行重定向),而307则继承了HTTP 1.0中302的规范(即如果原请求是post,则不允许进行自动重定向,结果是post不重定向,get可以自动重定向)。

The response to the request can be found under a different URL and SHOULD be retrieved using a GET method on that resource. This method exists primarily to allow the output of a Post-activated script to redirect he user agent to a selected resource. The new URI is not a substitute reference for the originally requested resource. The 303 response MUST NOT be cached, but the response to the second ( redirected ) request might be cacheable.

The different URI SHOULD be given by the Location field in the response . Unless the request method was HEAD , the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI ( S ) .

Note: Many pre-HTTP/1.1 user agents do not understand the 303 status. When interoperability with such client is a concern, the 302 status code may be used instead, since most user agents react to a 302 response as described here for 303.

307

在http 1.1规范中,307为临时重定向,注意划红线的部分,如果重定向307的原请求不是get或者head方法,那么浏览器一定不能自动的进行重定向,即便location有url,也应该忽略。

也就是307继承了302在HTTP 1.0中的规范(303继承了302在HTTP 1.0中的实现)。

If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT atomatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.

3. 小结

在HTTP 1.0规范中,302的规范并没有被服务器和浏览器遵守,即规范和实现出现了二义性,因此在HTTP 1.1中,将302的规范和实现拆分成了303和307。

三、结论

虽然在不同版本的http规范中对重定向赋予了不同的语义,但是因为使用历史和服务器实现等原因,在实际中并不一定安全按照http规范实现,因此我个人感觉上述讨论只是一个了解,在实际写代码中302还是继续用吧···

参考:

1. 《http 1.0规范》
2. 《http 1.1规范》

3. 博客:点击打开链接

附注:

本文如有错漏,烦请不吝指正,谢谢!

【HTTP】http重定向301/302/303/307相关推荐

  1. php 303,HTTP 的重定向301,302,303,307(转)

    301 永久重定向,告诉客户端以后应从新地址访问. 302 作为HTTP1.0的标准,以前叫做Moved Temporarily ,现在叫Found. 现在使用只是为了兼容性的处理,包括PHP的默认L ...

  2. 详解重定向(HTTP状态码301/302/303/307/308)附案例

    关注 前端瓶子君,回复"交流" 加入我们一起学习,天天进步 今天打算好好把状态码301.302.303.307.308好好撸一遍,并会测试下一些例子. 状态码的解释 我们都知道重定 ...

  3. http 301 302 303 307 308 傻傻分不清

    http的重定向我们经常是张口就来,"小明,在nginx上做一个重定向就行了".整个流程非常简单,服务端HTTP返回码是30x,头里面的Location字段代表新的URL.如下图所 ...

  4. 网站优化之尽量避免重定向(301/302)

    重定向会增加http请求的次数,会影响到整个网站的性能,但是必要的重定向又可以提高用户体验,所以我们需要在性能和用户体验之间去权衡,达到最好的目的:下面讲讲php实现301永久重定向和302临时重定向 ...

  5. http协议状态码3xx系列(301,302,303,304,305,306,307),小白易通

    3xx 重定向 3xx系列是http响应包中重要的状态标准,表示重定向意义的一类状态码,这些转状态码将指导客户端执行某些行为 都是属于重定向,但不同的值,差异却不小,具体差异如下 301 永久重定向 ...

  6. http 状态码 301 302 303 区别

    301 永久性重定向,该状态码表示请求的资源已被分配了新的URL,以后应使用资源现在所指的URL 302 临时重定向.表示请求的资源已被分配了新的URL,希望用户本次使用新的URL访问.和301相似, ...

  7. http中的301、302、307、308有什么区别?

    原文来自https://www.cnblogs.com/wuguanglin/p/redirect.html 状态码的解释 301 Moved Permanently(永久移动) 被请求的资源已永久移 ...

  8. 重定向301和302区别详解(转)

    301和302是最常见的HTTP重定向代码. 301永久重定向 301重定向是指示链接的目标已永久将URL更改为不同的URL,例如,当seoexample更名为example时,他们将URL从seoe ...

  9. [html] http中的301、302、307、308有什么区别?

    [html] http中的301.302.307.308有什么区别? 301:永久移动302:发现307:临时重定向308:永久重定向 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, ...

最新文章

  1. java redis管理_优雅时间管理Java轻松做到,想学么?
  2. elastic的gc相关
  3. [Offer收割]编程练习赛50
  4. 十种MySQL报错注入
  5. Educational Codeforces Round 8 D. Magic Numbers 数位DP
  6. Static关键字测试
  7. SAP系统中发送消息的几种办法
  8. mongo在哪创建管理员_MongoDB添加用户
  9. Error:Could not resolve all files for configuration ':app:preDebugCompileClasspath'. Could not fin
  10. Pytorch的BatchNorm层使用中容易出现的问题
  11. MySQL学习笔记_8_SQL语言基础复习
  12. 电力物联网智慧路灯充电桩传感器技术应用方案
  13. 使用Qtip2来开发功能强大的删除和信息提示功能
  14. 数据库截取字段 转换成int型函数
  15. lambda表达式学习使用实例
  16. SecureCRT 64位 安装破解版v8.1.4
  17. 实验12 网络资源共享
  18. Kettle数据从txt到数据库表,表到文件
  19. 明翰英语教学系列之方法篇
  20. CUDA 深入浅出谈[转]

热门文章

  1. 会议室怎么添加预约功能?快速解决会议室使用效率问题
  2. 什么是版本控制和版本控制工具?
  3. suricata-update管理规则
  4. 联发科MTK6737安卓4G全网通智能模块核心板规格书
  5. 有赞Vant webapp步骤条组件插入组件icon
  6. 【无线射频技术笔记】器材篇:屏蔽箱
  7. 深入理解web Worker
  8. 解决kaldi报错copy-feats: error while loading shared libraries: libmkl_intel_lp64.so: cannot open shared
  9. 关于洛古p1019单次接龙的一点看法
  10. vue设置页面背景及背景图片