在最近的项目中,遇到这样一个场景:合作方开发H5页面并部署在合作方的服务器上,但页面中嵌入了我方的SDK,SDK会直接调用我方的接口,如下图:
文章插图
但是控制台中却会收到如下报错:
Access to XMLHttpRequest at 'http://example1.com/test' from origin 'http://example2.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这就是跨域的报错 。跨域是什么跨域,是指浏览器不能执行其它网站的脚本 。它是由浏览器的同源策略造成的,是浏览器对JAVAscript实施的安全限制 。
简单来讲,就是从地址A加载的页面,不能访问地址B的服务(如上图) 。此时地址A与地址B不同源 。
所谓同源,就是域名、协议、端口均相同 。举个例子:
http://www.123.com/index.html 调用 http://www.123.com/abc.do (非跨域)http://www.123.com/index.html 调用 http://www.456.com/abc.do (主域名不同:123/456,跨域)http://abc.123.com/index.html 调用 http://def.123.com/server.do (子域名不同:abc/def,跨域)http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.do(端口不同:8080/8081,跨域)http://www.123.com/index.html 调用 https://www.123.com/server.do (协议不同:http/https,跨域)
如上所述,由于合作方的域名与我方的域名不同,从合作方加载的页面,调用我方接口的时候,就会出现跨域的报错 。是否有办法可以解决这个问题呢,需要从CORS说起 。
CORS随着互联网的发展,同源策略严重影响了项目之间的连接,尤其是大项目,需要多个域名配合完成,因此W3C推出了CORS,即Cross-origin resource sharing(跨来源资源共享) 。CORS的基本思想就是使用额外的HTTP头部让浏览器与服务器进行沟通,从而决定是否接受跨域请求 。
CORS需要浏览器和服务器同时支持,目前,所有浏览器都支持该功能 。对于开发者来说,CORS通信与同源的AJAX通信没有区别,代码完全一样 。浏览器在跨域访问时,会自动添加HTTP头信息,或者发起预检请求,用户对此毫无感知 。因此是否支持跨域请求,关键在于服务器是否做了CORS配置,允许跨域访问 。
浏览器将跨域请求分为两类:简单请求和非简单请求 。
同时满足以下两大条件的,就属于简单请求:
- 请求方法是以下3种之一:GETPOSTHEAD
- HTTP头信息不超出以下字段:AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-Type:仅限于三个值Application/x-www-form-urlencoded、multipart/form-data、text/plain
对于这两种请求,浏览器的处理方式是不一样的 。
简单请求对于简单请求,浏览器采用先请求后判断的方式,即浏览器直接发出CORS请求,即在请求头中增加Origin字段,如图:
文章插图
Origin字段用来向服务器说明,本次请求来自于哪个源(协议+域名+端口),服务器决定是否允许这个源的访问 。
服务器判断该源如果不在自己允许的范围内,就返回一个正常的HTTP响应 。浏览器判断响应头中是否包含Access-Control-Allow-Origin字段,如果没有,浏览器就知道服务器是不允许跨域访问的,就会抛出错误 。
如果Origin在服务器允许的范围内,服务器的HTTP响应中,就会包含如下字段:
文章插图
Access-Control-Allow-Origin 它的值要么是请求时Origin字段的值,要么是一个*(表示接受任意域名的请求) 。 Access-Control-Allow-Credentials 它的值是一个布尔值,表示是否允许发送Cookie 。默认情况下,Cookie不包括在CORS请求之中 。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器 。 Access-Control-Allow-Headers 允许浏览器在CORS中发送的头信息 。 Access-Control-Allow-Methods
允许浏览器在CORS中使用的方法 。
浏览器收到服务器返回的HTTP响应后,即可知道什么样的CORS请求是被允许的 。
非简单请求对于非简单请求,浏览器采用预检请求,询问服务器是否支持跨域请求 。在正式的请求之前,浏览器会预先发送一个额外的OPTIONS请求,询问服务器当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP方法和头字段 。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错 。如图:
推荐阅读
- SEO的精益优化方法论
- 这款容量最大可达1T的"U盘",传输速度快至900MB/s多
- 恒星全部死亡后的宇宙
- 人死后会投胎吗?真相竟然是这样的 人死了后会投胎吗
- 富士急鬼屋三楼吓死人的故事 日本富士急鬼屋3楼真的有鬼
- 讲讲用了云桌面的真实体会
- 清朝有公主吗 清朝末代公主
- 诸葛亮称帝了吗 诸葛亮为什么不当蜀国的皇帝
- 我如何将软件系统的性能提高35,000%
- Gitee大神们的算法/数学相关开源项目推荐