浏览器的同源策略
所谓同源策略,就是指浏览器会限制从一个源加载的网页和脚本与其他源的资源交互。这是一种用于隔离潜在恶意软件的机制。
可能有人会奇怪,明明网页是自己写的,自己怎么会请求含有恶意程序的URL呢?话虽如此, 可是我们在开发中经常会引入第三方的库,当我们通过script
标签将它们引入的时候是没有限制的。而它们之中就可能含有对恶意URL的请求。
所谓同源,就是指两个URL的协议、主机、端口要一致。这就能看出同源策略的思路–“信任自家人”。因为同源的两个URL一般都是来自同一个企业或者个人,自己人不会坑自己人。
例如对http://store.company.com/dir/page.html
的同源检测:
注:上面说“限制”,既指浏览器限制脚本发起跨域请求,也指浏览器允许发起跨域请求,但是响应被浏览器拦截
CORS
同源策略默认阻止跨域获取资源。但是CORS给了web服务器这样的权限,即服务器可以选择,允许跨域请求访问到它们的资源。
CORS,即Corss-Orgin Resource Sharing,跨域资源共享。这是一个由一系列HTTP首部字段组成的系统,这些首部字段决定了浏览器是否阻止脚本中代码发起的跨域请求。
例子
假设当前页面的URL为http://www.a.com
,现在我想对http://www.b.com
发起请求。
那么请求头中会包含一个Origin
字段,值即为http://www.a.com
。
响应头中则会包含Access-Control-Allow-Origin
字段,该字段表示服务器允许哪些源发起的访问。若该字段的值为*
或http://www.a.com
,则跨域访问成功,若都不是,则跨域请求被浏览器拦截。
预检请求
对于一些“也许会对服务器造成影响”的请求(例如PUT
、带有参数的POST
、DELETE
等),浏览器会首先使用OPTIONS
发起一个预检请求,以便提前获知服务器是否可以允许后续将要发出的正式请求。
预检请求的首部中会包含两个字段Access-Control-Request-Method
和Access-Control-Request-Headers
。
例如,Access-Control-Request-Method: POST
,Access-Control-Request-Headers:Content-Type
就是告知服务器我将使用POST方法发起请求,并且请求首部字段中会包含一个Content-type
。
而在服务器的响应中会包含Access-Control-Allow-Methods
、Access-Control-Allow-Headers
、Access-Control-Max-Age
。
前两个字段分别表示服务器允许请求的方法和服务器允许请求首部包含的字段。
而第三个字段表示在字段值所指定的时间内不必再次预检。