当前位置: 首页 > news >正文

HTTP状态码302、303和307的故事

《HTTP权威指南》第3章在讲解30X状态码时,完全没有讲清楚为什么要有302、303、307,以及他们的关系,一句“问题出在HTTP/1/1”让我一头雾水,莫名其妙;而第五章在讲重定向响应时,没有说到现在很常见的302,反而是说我从没遇到过的303和307。很是迷惑,对于这3个状态码,WiKi和RFC文档都有详解,下面我以我的思维添油加醋的描述一遍。

一、状态码——302

    RFC1945( http://tools.ietf.org/html/rfc1945#page-34),也就是HTTP1.0在介绍302时说,如果客户端发出POST请求后,收到服务端的302状态码,那么不能自动的向新的URI发送重复请求,必须跟用户确认是否该重发,因为第二次POST时,环境可能已经发生变化(嗯,POST方法不是幂等的),POST操作会不符合用户预期。但是,很多浏览器(user agent我描述为浏览器以方便介绍)在这种情况下都会把POST请求变为GET请求。
    RFC2616( http://tools.ietf.org/html/rfc2616#section-10.3.3),也就是HTTP1.1在介绍302时说,如果客户端发出非GET、HEAD请求后,收到服务端的302状态码,那么就不能自动的向新URI发送重复请求,除非得到用户的确认。(又是-,-)但是,很多浏览器都把302当作303处理了(注意,303是HTTP1.1才加进来的,其实从HTTP1.0进化到HTTP1.1,浏览器什么都没动),它们获取到HTTP响应报文头部的Location字段信息,并发起一个GET请求。

二、状态码——303和307

    从上面的介绍可以知道,HTTP1.1和HTTP1.0的302状态码意义是一样的,浏览器对它的处理也是一样的。POST方法的重定向在未询问用户的情况下就变成GET,这种不符合文档规范的问题依然存在。实践在前而文档在后,HTTP1.1把这种POST变GET的行为纳入了RFC文档:HTTP1.1新加入303和307状态码。
    文档中规定303状态码的响应,也就是上边提到的现在浏览器对302状态码的处理:POST重定向为GET。
    HTTP1.1文档中307状态码则相当于HTTP1.0文档中的302状态码,当客户端的POST请求收到服务端307状态码响应时,需要跟用户询问是否应该在新URI上发起POST方法,也就是说,307是不会把POST转为GET的。
    从网络上搜索到这个说法“303:对于POST请求,它表示请求已经被处理,客户端可以接着使用GET方法去请求Location里的URI。 307:对于POST请求,表示请求还没有被处理,客户端应该向Location里的URI重新发起POST请求。”,从上面的介绍可以明白,这个说法是臆想而已,文档并没有这么说,而业界是否统一如此处理,还不好说,我没有抓到过307和303的包。
    文档也说到,为兼容很多HTTP1.1之前的浏览器,服务端在需要发出303状态码时,会选择用302状态码替代;而对于307的处理,则需要在响应实体中包含信息,以便不能处理307状态码的用户有能力在新URI中发起重复请求,也就是说,把重定向的页面展示给用户,让用户去点重定向URI链接(URI现在基本就是URL)。

三、总结

    303和307是HTTP1.1新加的服务器响应文档的状态码,它们是对HTTP1.0中的302状态码的细化,主要用在对非GET、HEAD方法的响应上。文档规定: 浏览器对303状态码的处理跟原来浏览器对HTTP1.0的302状态码的处理方法一样;浏览器对307状态码处理则跟原来HTTP1.0文档里对302的描述一样。 
    303和307的存在,归根结底是由于POST方法的非幂等属性引起的。
    在HTTP1.1中,302理论上是要被放弃掉的,它被细化为303和307,但为了兼容,它目前还在业界中大量使用,而303和307状态码我还没遇到过(没有使用场景,也没抓到过这样的响应报文)。为什么业界少使用303和307呢?对于GET和HEAD方法来说,307是没必要存在的,用302或者303就可以满足需求了,307仅在POST方法的重定向上有用处。所以我猜测它们少见的原因有两方面:1、POST方法重定向的使用场景太少,使得307状态码没有用武之地;2、GET方法虽然常需要使用的重定向,但使用302状态码也能正确运转,再考虑到微乎其微的兼容问题(现在的浏览器怎么可能不支持HTTP1.1呢!),也就没有使用303的必要了。
   
本文转自:http://www.cnblogs.com/cswuyg/p/3871976.html

转载于:https://www.cnblogs.com/jq-melody/p/5210288.html

相关文章:

  • MongoDB的复制集
  • NSString 截取字符串的某一个部分
  • 联想扬天A4680R台式电脑增加内存不识别的解决方案
  • webservice 单元测试(vs2010)
  • Gesture Recognizers与触摸事件分发
  • 批量上传工具
  • Mac Book Pro 374 2010 Mid 款升级10GB内存
  • HDU 2844 Coins (多重背包)
  • 回味基础
  • 【sehll学习】linux运维一个简单shell脚本监控系统内存
  • 利用WebClient上传参数及文件流到远程ashx服务
  • 配置 yum 源的两种方法
  • apache 配置防盗
  • android TabWidget 位置
  • 浅析selenium的page object模式
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • Fabric架构演变之路
  • golang 发送GET和POST示例
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • Java教程_软件开发基础
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • node学习系列之简单文件上传
  • NSTimer学习笔记
  • vue.js框架原理浅析
  • 编写符合Python风格的对象
  • 机器学习中为什么要做归一化normalization
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 一些关于Rust在2019年的思考
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #pragma data_seg 共享数据区(转)
  • #QT(一种朴素的计算器实现方法)
  • #单片机(TB6600驱动42步进电机)
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #快捷键# 大学四年我常用的软件快捷键大全,教你成为电脑高手!!
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (五)Python 垃圾回收机制
  • (五)网络优化与超参数选择--九五小庞
  • (转)Google的Objective-C编码规范
  • .bat批处理出现中文乱码的情况
  • .NET Core 通过 Ef Core 操作 Mysql
  • .net 按比例显示图片的缩略图
  • .NET使用存储过程实现对数据库的增删改查
  • .NET下的多线程编程—1-线程机制概述
  • :not(:first-child)和:not(:last-child)的用法
  • @cacheable 是否缓存成功_让我们来学习学习SpringCache分布式缓存,为什么用?
  • [2021 蓝帽杯] One Pointer PHP
  • [383] 赎金信 js
  • [Android Pro] android 混淆文件project.properties和proguard-project.txt
  • [c++] 什么是平凡类型,标准布局类型,POD类型,聚合体
  • [C++]18:set和map的使用