美文网首页Web前端之路让前端飞
same origin policy & CORS ---

same origin policy & CORS ---

作者: 柚吖柚柚子 | 来源:发表于2019-10-28 14:56 被阅读0次

跨域对于前端来讲是个耳熟的字眼,在日常工作和面试中经常出现。
本文介绍了同源策略CORS跨域资源共享实际开发中如何处理跨域这几个方面。

前端开发过程中,你肯定见过这个报错。Access to fetch at 'https://m.demo.com' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. 这就是跨域请求被浏览器拦截没跑了。

same origin policy & CORS

同源策略 (same origin policy),是浏览器最核心、最基本的安全功能之一。它限制了从一个源(origin)加载的文档如何与另外一个源的资源进行交互。
Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头。
更详细的说,是浏览器对在脚本内跨源发起的 http请求 的response结果进行了拦截
想象一下,如果没有这个策略限制,就会发生某一个源随意调用其他源的接口获取他人数据,篡改他们数据……等等肥肠价值观警告的事情。

该策略常见的三种情况:

  • Cross-origin writes 跨域写 例如链接links、重定向、表单提交……
  • Cross-origin embedding 资源嵌入 比如 script 、link、img、video等标签嵌入资源
  • Cross-origin reads 跨域读 但可通过嵌入巧妙绕过

同源就是指两个页面的协议、主机、端口号(如果有)三者皆一致。 当一个资源a从一个与该资源a所在服务器a不同协议、域或端口 的服务器b上请求另一个资源b,这就发起了一个跨域HTTP请求。

exp:http:/ / www. baidu. com:80 http即协议,www. baidu . com即主机,80即端口号。

但有时候开发中,确实存在这样、那样的跨域资源获取需求。这就要讲到跨域资源共享(Cross-Origin Resource Sharing) ,允许服务器声明 哪些 有权限通过浏览器 访问哪些资源。给我们争取一个跨域请求的机会。
借用个栗子,客户端发起一个simple request get请求:

image
  • Client request header请求头 get 请求获取 /resources/public-data/ 下的资源
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/\*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http:\/\/foo.example\/examples\/access-control\/simpleXSInvocation.html
Origin: http:\/\/foo.example
  • Server response header 响应头
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61 
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

[XML Data]

服务端返回的 Access-Control-Allow-Origin: *表明,该资源可被任意外域访问。
ps:如果服务器仅希望某个源(比如http:/ /examples.com)可以访问其资源,只需设置 Access-Control-Allow-Origin: http:/ /examples.com 。如果希望仅允许GET请求或多种请求,则可设置 Access-Control-Allow-Methods:GET, POST, ……

解决方法

已知的一些方法在生产环境几乎都需要server进行配合,本地开发的话前端是完全可以自行绕过跨源问题。

方法如下(前四种适用于生产环境):
1、后端在reponse header中添加 Access-Control-Allow-Origin: xxx允许跨源请求。

exp,http: //hello-world.example 想访问 http: //example.com 的资源。 http: //example.com 在response header 中添加 Access-Control-Allow-Origin: http: //hello-world.example
当然 也可以一了百了添加 Access-Control-Allow-Origin: * ,只要你确保不会产生其他副作用。

2、前端使用JSONP

像一些资源标签(如img,video,script……)允许跨源资源嵌入,即标签的src是允许嵌入跨源资源的。jsonp其实就是通过 script src 传递参数(请求参数、约定的callback name)给服务器,服务器将返回数据包裹在回调函数中,直接在脚本中进行调用达到跨域获取资源数据的效果。

3、document.domain,允许子域安全访问其父域。

document.domain 的值可以设置为其当前域或其当前域的父域。如果将其设置为其当前域的父域,则这个较短的父域将用于后续源检查。(设置后当前域端口号会被重写为Null)
举个栗子,假设http: //demo.example.com中有一个脚本执行了 document.domain = 'example.com'; 那么浏览器将会通过对http: //company.com/dir/page.html (http: //company.com/dir/page.html 也必须设置document.domain = 'example.com'; 以重置端口号)资源的同源检测。

4、OPTIONS预检请求

preflight request 是一个包含了:Access-Control-Request-MethodAccess-Control-Request-Headers,以及一个 Origin 首部的options请求。服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。
对于可能对服务器数据产生副作用的请求(GET以外,搭配某些MIME type的请求),浏览器都会先发出一个预检请求,以监测服务器是否允许该类型的请求。确认允许后,才会发出实际请求。
OPTIONS 请求用于获取目的资源所支持的通信选项。

5、如果是本地开发,还可使用chrome - Allow CORS: Access-Control-Allow-origin插件允许跨域,或命令行 open -a "Google Chrome" --args --disable-web-security --user-data-dir

chrome插件的做法应该就是在 response 达到浏览器前,在 response header 中添加了 Access-Control-Allow-Origin 和 Access-Control-Allow-Methods 两个字段来达到允许跨域资源共享的原理。

6、webpack proxy可以在开发环境代理跨域请求,但build打包后,代理是不生效的,请注意这点。

参考资料

CORS:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
浏览器同源策略:https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
Document.domain:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/domain
W3C Cross-Origin Resource Sharing:https://www.w3.org/TR/cors/

如有遗漏的方法 欢迎补充讨论 ~

相关文章

网友评论

    本文标题:same origin policy & CORS ---

    本文链接:https://www.haomeiwen.com/subject/joqsvctx.html