天天看点

iOS 防 DNS 污染方案调研 --- 302等 URL 重定向业务场景

302等 url 重定向业务场景需要解决的问题:

302 等重定向状态码,如何正确执行跳转逻辑,要求跳转后,依然需要执行 ip 直连逻辑,多次 302,也能覆盖到。

302等 url 重定向业务场景问题主要集中在 post 请求上,解决方案的方向大致有几种:

将请求方式统一替换为 get

解决 post 请求时的重定向问题

将 url 统一替换为 get,这种方案在客户端这边是成本最低的,如果团队中达成一致是最好的。不过限制也是显而易见的。那么我们就着重讨论下如何解决 post 请求时的重定向问题。

对于 get 请求,重定向问题较为简单,我们着重讨论下 post 请求的重定向问题,看下不同状态码下的响应方式。

下面介绍下重定向的类型以及解释:

重定向的类型

对应协议

解释

300 multiple choices

http 1.0

可选重定向,表示客户请求的资源已经被转向到另外的地址了,但是没有说明是否是永久重定向还是临时重定向。

301 moved permancently

永久重定向,同上,但是这个状态会告知客户请求的资源已经永久性的存在在新的重定向的 url 上。

302 moved temporarily

临时重定向,在 http1.1 中状态描述是 found,这个和 300 一样,但是说明请求的资源临时被转移到新的 url 上,在以后可能会再次变动或者此 url 会正常请求客户的连接。

303 see other

http 1.1

类似于 301/302,不同之处在于,如果原来的请求是 post,location 头指定的重定向目标文档应该通过 get 提取(http 1.1新)。

304 not modified

并不真的是重定向 - 它用来响应条件 get 请求,避免下载已经存在于浏览器缓存中的数据。

305 use proxy

客户请求的文档应该通过 location 头所指明的代理服务器提取(http 1.1新)。

306

已废弃,不再使用

307 temporary redirect

和302(found)相同。许多浏览器会错误地响应 302 应答进行重定向,即使原来的请求是 post,即使它实际上只能在 post 请求的应答是 303 时 才能重定向。由于这个原因,http 1.1新增了 307,以便更加清楚地区分几个状态代码:当出现 303 应答时,浏览器可以跟随重定向的 get 和 post 请求;如果是 307 应答,则浏览器只能跟随对 get 请求的重定向。(http 1.1新)

因为常见的重定向为 301、302、303 307,所以下面重点说说这几种重定向的处理方法。

http1.0 文档中的 302(或301) 状态码,原则上是要被废弃的,它在 http1.1 被细分为了 303 和 307。不过 303 和 307 应用并不广泛,现在很多公司对 302(或301) 处理实际上是 303。

总结起来就是:

协议

状态码

协议规定

实际情况

http1.0

302(或301)

不建议使用

仍在大面积使用

http1.1

303 + 307

旧有302(或301)被细分,并建议使用的新的状态码

应用面积较小

这些新旧协议的主要差别集中在 post 请求的重定向处理上:

对于301、302的location中包含的重定向url,如果请求method不是get或者head,那么浏览器是禁止自动重定向的,除非得到用户的确认,因为post、put等请求是非冥等的(也就是再次请求时服务器的资源可能已经发生了变化)

另外注意307这种情况,表示的是 post 不自动重定向为 get ,需要询问访问当前 url 的用户,是否需要重定向,进行手动重定向。

目前浏览器大都还把302当作303处理了(注意,303是http1.1才加进来的,其实从http1.0进化到http1.1,浏览器什么都没动),它们获取到 http 响应报文头部的 location 字段信息,并发起一个 get 请求。

我们可以根据业务需要,对不同的状态码做处理,比如可以对303状态码做如下处理,

location 中包含重定向 url 就重定向

如果是 post 请求修改为 get 请求,并清空 body。

清空 host 信息

重新发送网络请求

代码示例:

可以在该回调函数里拦截302请求,copy request,在 request header 中带上 cookie 并重新 loadrequest。不过这种方法依然解决不了页面 iframe 跨域请求的 cookie 问题,毕竟-[wkwebview loadrequest:]只适合加载 mainframe 请求。

如果通过之前篇幅里提到的 ios11 的新 api 进行处理,也就不会有该问题。

相关的文章:

<a href="https://zhuanlan.zhihu.com/p/24990222">《wkwebview 那些坑》</a>

<a href="http://www.cnblogs.com/cswuyg/p/3871976.html">《http状态码302、303和307的故事》</a>

<a href="http://en.wikipedia.org/wiki/http_302">http 302 wiki</a>

<a href="http://tools.ietf.org/html/rfc1945#page-34">rfc1945</a>

<a href="http://tools.ietf.org/html/rfc2616#section-10.3.3">rfc2616</a>

补充说明:

概念

举例

host

可以是 ip 也可以是 fqdn。

www.xxx.com 或 1.1.1.1

fqdn

fully qualified domain name,由主机名和域名两部分组成

www.xxx.com

域名

域名分为全称和简称,全称就是fqdn、简称就是 fqdn 不包括主机名的部分

比如:xxx.com ,也就是www.xxx.com 这个 fqdn 中,www 是主机名,xxx.com 是域名。

文中部分提到的域名,如果没有特殊说明均指的是 fqdn。