简单的说,没有遵照浏览器“同源政策”的操做,就是跨域。html
虽说 cookie 不能跨域, 可是子域之间、子父域之间是能够共享的, 就是经过 document.domain
.
cookie共享, eg:前端
// http://aa.test.com/a.html // http://bb.test.com/bb.html // 只要设置相同的主域, a.html & b.html 就能够共享cookie document.domain = 'test.com'; // a.html document.cookie = "testData=helloWorld"; // b.html var cookieYes = document.cookie;
还能够在服务器设置cookie的一级域名, 这样就不用在2、三级域名下设置了. eg:
Set-Cookie: key=value; domain=.test.com; path=/
PS: 这种方式, 只适用于 cookie 和 iframe 的访问, localstorage 和 indexDB 都是不能够的, 须要经过 postMessage.web
在好久的之前, 对于不支持 XMLHttpRequest 的浏览器的最佳回溯方法之一就是使用 iframe 对象, 固然常规只是用来实现流模式的Comet.
不得不说, 一些正常没法实现的功能/某些兼容的处理, 不少奇淫技巧都是借助 iframe 完成的.ajax
看看借助iframe在跨域中通讯.父窗口打开 http://test1.com
, iframe子窗口打开 http://test2.com
.json
/* 父窗口给子窗口通讯 */ // test1.com var src = url + '#' + data; iframe.src = src; // test2.com 监听 hashchange window.onhashchange = handleChange; function handleChange() { var data = location.hash; } /* 子窗口给父窗口通讯 */ // test2.com parent.location.href = url + '#' + data; // ...
// 子窗口 test2.com window.name = data; // 父窗口 test1.com var data = iframe.contentWindow.name; // window.name 能够携带大量信息,可是这样必须得监听子窗口 window.name 的变化
不论是 hash url, 仍是 window.name, 老是给人一种奇淫技巧的感受, 有木有? 接下来的这个就不同了, 它就是HTML5专为了解决这样问题而诞生的新朋友: 跨文档通讯(Cross-document messaging)
核心的方法就是 window.postMesage , 无论俩窗口是否同源, 都容许跨窗口通讯.跨域
/* 窗口1 aa.com */ var popup = window.open('http://aa.com'); // 向 bb.com 发消息 popup.postMessage("hello, bb!", "http://bb.com"); function receiveMessage(event) { // 能够过滤掉不是 bb.com 传来的消息 if (event.origin !== "http://bb.com") return; // event.source is popup // event.data is "hi there yourself! the secret response is: rheeeeet!" } window.addEventListener("message", receiveMessage, false); /* 窗口2 bb.com */ function receiveMessage(event) { if (event.origin !== "http://aa.com") return; // event.source is window.opener // event.data is "hello, bb!" event.source.postMessage("hi there yourself! the secret response is: rheeeeet!", event.origin); } window.addEventListener("message", receiveMessage, false);
这样子, localStorage 跨域也就能搞定啦.浏览器
ajax 请求也是受到同源限制的, 若是我想访问第三方网站的接口怎么办呢? 目前有三个办法: jsonp / cors / websocket.缓存
基本思路是: 经过 script.src 请求 json 数据, 约定一个回调函数名将 json 包裹得到数据安全
function getScript(url) { var _script = document.createElement('script'); _script.src = url; var body = document.getElementsByTagName("body")[0]; body.appendChild(script); } function f(data) { alert(data.name); } getScript("http://test.com/jsonp?callback=f");
jsonp 简单易用, 可是也只能发送发 get 请求.
ps: 实际上呢, 经过 src 方式的get请求, 都是不受同源限制, 能够跨域的. 好比图片 img.src = 'test1.com'.服务器
跨域资源共享(Cross-origin resource sharing), 容许向跨域服务器发出 XMLHttpRequest 请求, 怎么作到的呢?
基本思路: 使用自定义的HTTP头部让浏览器与服务器进行沟通, 从而决定请求或响应是成功仍是失败. 因此须要客户和服务器两端支持; 对于客户端来讲,感知不大, 和通常 ajax 请求彷佛没有差异; 主要是对于服务端来讲, 实现了 CORS 接口, 一切就ok.
CORS的处理流程:
IE10- 的兼容处理:
引入 XDR(XDomainRequest), 实现安全可靠的跨域通讯.
websoket 是一种通讯协议, 基于 TCP/IP. 它不实施同源政策, 因此基本思路是, 只要服务器设置 origin 经过, 就能够跨域
GET /xxx HTTP/1.1 Host: test1.com Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: xxxxxxxxxxxxxxxxxxxxxxx== Sec-WebSocket-Protocol: xxx Sec-WebSocket-Version: xx Origin: http://test2.com
若是 Origin: http://test2.com 在白名单中, 就能够进行通讯了.
服务器这是会把 http 转换成 ws 协议
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: xxxxxxxxxxxxxxxxxxxxxxx== Sec-WebSocket-Protocol: xxx
基本思想: 首先将请求发送给后台服务器, 经过服务器来发送请求, 而后将请求的结果传递给前端.
xhr.open('POST', 'http://localhost:8888/proxy?http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer', true);
参考《木的树》