跨域请求基础知识
浏览器的同源策略
浏览器的源指的是 协议://域名:端口 这样的URL组合。我们首先要明确几点
www.foo.com 和 foo.com 是不同域
www.foo.com 和 www.foo.com/b/1 是同域的,因为浏览器的源中不包含路径
https 和 http 的协议不同,是不同域
当以上三个元素中的一个与网页的document.domain不相同时,浏览器会认为你的请求是跨越请求。
cookie机制
经常容易与同源策略搞混的是cookie的发送机制。
cookie 可以通过设置domain 为 domain=".foo.com" , 这样设置如果用户访问的www.foo.com 或是user.foo.com 那么这个cookie都会被发送
cookie 可以通过这事path 为 path="/auto/" ,这样设置如果用户访问的是www.foo.com/user时将不会发送这个cookie
修改当前域
可以通过设置document.domain 为当前域的一个后缀来修改当前域,例如 可以将域名为 www.foo.com 的document.domain 设置为 foo.com : document.domain="foo.com"来绕过一些跨域问题。
浏览器 -- 浏览器的跨域访问
可以通过window.postMessage()来解决浏览器中不同页面不同域名的通信问题
浏览器 -- 服务器的跨域访问
浏览器跨域访问不同域的服务器的解决方案一般有三种
jsonp,利用JavaScript加载没有同域策略的机制。一般返回的数据格式是:callback(json);
Iframe间通信,在当前页面下append一个Iframe。例如
$(document.body).append('');
$('iframe#authIframe').attr('src', CONST_CONTENT_ROOT_URL+'/index.jsp');
$('iframe#authIframe').load(function(){
});
服务器返回带有HTTP access control 的头来实现跨域访问。
HTTP access control (CORS)
使用Access-Control的跨域请求有两种,简单的跨域请求和带有先导请求(options)的跨域请求
简单的跨域请求
简单的跨域请求和带有先导请求的跨域请求最大的区别是他不会先发送一个先导请求。
浏览器对简单的跨域请求的定义是
请求方法是get,post,head中的一种
content-Type必须为application/x-www-form-urlencoded, multipart/form-data, 或text/plain中的一种
没有自定义请求头
带有先导请求(options)的跨域请求
带有先导请求(options)的跨域请求,浏览器会自动先发送一个options方法的请求到服务器端,并查看相应头里是否有Access-Control头部。值得注意的是options方法的请求并不会携带cookie,也就是如果如果你的请求必须要登陆验证的话那么你就必须构造一个简单请求。
下面是一些常用的Access-Control头部
请求头
Access-Control-Request-Method : 先导请求中的请求头,告诉服务器真实请求的http方法
Access-Control-Request-Headers :先导请求中的请求头,告诉服务器真实请求的http请求头
相应头
Access-Control-Allow-Origin :服务器允许跨域请求的origin
Access-Control-Expose-Headers : 允许JavaScript读取的头部
Access-Control-Allow-Credentials :是否允许携带cookie
Access-Control-Allow-Methods :允许的请求方法
Access-Control-Allow-Headers :允许的请求头部
由于水平有限,出错难免,如有出错,还望指正,谢谢!