WKWebView跨域和CORS研究

跨域之浏览器同源策略

定义:同源策略是指在不同源的资源不允许访问

源的定义:协议+主机+端口

举例:

http://www.baidu.com/index.html中有一个ajax请求 http://www.google.com/getUserInfo

由于host不一致,即www.baidu.com != www.google.com 因此浏览器判断非同源 将禁止访问

Tips:当ajax请求由于同源策略禁止的时候,request仍然会发送,也会收到response,只不过浏览器收到response后选择了忽略而已

同源策略限制的范围:

  • Cookie、LocalStorage 和 IndexDB 无法读取。
  • DOM 无法获得。
  • AJAX 请求不能发送。

如何实现跨域访问之CORS

CORS是跨域资源共享的简写,是w3c的标准,用于当发生跨域请求的时候,需要浏览器和服务端同时支持才能访问非同源资源,是实现跨域请求最广泛的方案之一

浏览器将CORS请求分成两类:

简单请求(simple request)和非简单请求(not-so-simple request)。

只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

这是为了兼容表单(form),因为历史上表单一直可以发出跨域请求。AJAX 的跨域设计就是,只要表单可以发,AJAX 就可以直接发。

凡是不同时满足上面两个条件,就属于非简单请求。

浏览器对这两种请求的处理,是不一样的。

简单请求:浏览器会在请求header中加上Origin字段,用于说明本次请求来自哪个源(协议+域名+端口)

服务器根据Origin字段判断是否允许访问,如允许访问则在response header中加入

Access-Control-Allow-Origin字段,标识允许哪些源访问

Access-Control-Allow-Credentials:标识是否允许发送cookie给服务器(CORS请求默认不允许cookie)

Access-Control-Expose-Headers:标识浏览器可以获取的额外的header字段(CORS请求返回后,默认浏览器只能获取六个header字段Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma)

非简单请求:此种请求会在正式请求之前加上一次预检请求(preflight),即通过一次options请求

在options请求的header中有以下字段

Origin: http://api.bob.com

Access-Control-Request-Method: PUT

Access-Control-Request-Headers: X-Custom-Header

分别标识当前请求的源、方法、特殊的请求头

服务器会返回以下header字段

Access-Control-Allow-Origin: *

Access-Control-Allow-Methods: GET, POST, PUT

Access-Control-Allow-Headers: X-Custom-Header

Access-Control-Allow-Credentials: true 

Access-Control-Max-Age: 1728000 //标识此次预检的有效期(单位秒),有效期内不必再次发出预检请求

预检通过后,接下来的流程同简单请求,request header加上origin, response header加上Access-Control-Allow-Origin

WKWebView中的跨域限制

H5所在位置分为本地加载、网络加载

一、H5在本地即在[NSBundle mainBundle]或者沙盒获取的文件

此时发送CORS简单请求header中的Origin为null

可通过设置WKWebView允许跨域

  WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];

     if (@available(iOS 10.0, *)) {

         [config setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];

    }

二、H5在服务器上

不可通过设置WKWebView进行跨域请求

iOS12在WKWebView的预检中需要返回Access-Control-Expose-Headers value不可指定为*

否则无法发起正常通信请求

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注