CORS
1. 同源策略
同源策略是指协议相同、域名相同、端口相同。
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
设想这样一种情况:A网站是一家银行,用户登录以后,又去浏览其他网站。如果其他网站可以读取A网站的 Cookie,会发生什么?
很显然,如果 Cookie 包含隐私(比如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往用来保存用户的登录状态,如果用户没有退出登录,其他网站就可以冒充用户,为所欲为。因为浏览器同时还规定,提交表单不受同源政策的限制。
由此可见,”同源政策”是必需的,否则 Cookie 可以共享,互联网就毫无安全可言了。
2. CORS
浏览器将CORS分为两种请求:简单请求和非简单请求
对于简单请求,浏览器检测到ajax跨域,会在请求头上添加origin字段,origin字段表示当前请求来自哪个源。如果origin指定的源,在许可范围,服务端返回的响应头中会有:access-control-allow-origin、acess-control-allow-credentials、Access-Control-Expose-Headers。如果origin指定的源,不在许可范围,服务端会正常返回,但是响应头中不会有access-control-allow-origin,从而浏览器抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。
对于复杂请求,会先发一个OPTIONS类型的预检请求,会携带origin、Access-Control-Request-Method、Access-Control-Request-Headers请求头。服务器收到”预检”请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。返回的响应头中Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers
一旦服务器通过了”预检”请求,以后每次浏览器正常的CORS请求,就都跟简单请求一样,会有一个Origin头信息字段。服务器的回应,也都会有一个Access-Control-Allow-Origin头信息字段。
3. iframe+window.name解决跨域问题
window.name属性的神奇之处在于name 值在不同的页面(甚至不同域名)加载后依旧存在(如果没修改则值不会变化),并且可以支持非常长的 name 值(2MB)。
在A页面,创建一个iframe,iframe的src设置为跨域服务器的地址。然后在iframe onload的时候将iframe的src换成和A页面同一个域名下的proxy页面。然后因为iframe的域名和A是同域,因此就能拿到iframe.contentWindow.name。
1 | <body> |
4. iframe+location.hash解决跨域问题
在A页面中创建一个iframe,iframe的src设置为跨域服务器的地址,跨域服务端改变iframe的location并将要传输的数据放在hash中传回。
1 |
|
可以看到跨域服务器将iframe的location设置为http://localhost:81/location-hash/proxy.html,并回传数据。
然后iframe在onload中获取iframe.contentWindow.location.hash。
1 | <body> |