同源策略
如果两个 URL 的协议、端口和域名都完全一致的话,则这两个 URL 是同源的。
跨域
如果协议、域名或者端口有一个不同就是跨域,Ajax 请求会失败。
实现跨域的方式
jsonp
- JSONP 使用简单且兼容性不错,但是只限于 get 请求
- 不安全, 不建议使用
- JSONP 的原理很简单,就是利用
// 注意: 要先定义函数,再添加<script>标签
<script>
function jsonp(data) {
console.log(data)
}
</script>
<script src="http://domain/api?param1=a¶m2=b&callback=jsonp"></script>
// 在开发中可能会遇到多个 JSONP 请求的回调函数名是相同的,这时候就需要自己封装一个 JSONP,以下是简单实现
function jsonp({url, params, cb}) {
return new Promise((resolve, reject) => {
// @ 1 : 定义 call back 函数
window[cb] = function (data) {
resolve(data)
document.body.removeChild(script)
}
// @ 2 : 设置url参数 'https://www.sdf.com' ---> 'https://www.sdf.com?wd=a&cb=callback'
url = `${url}?${stringify(params)}&cb=${cb}`
// @ 3 : 添加 script 标签
let script = document.createElement("script")
script.src = url
document.body.appendChild(script) // script标签将会调用window[cb]函数
})
}
function stringify(params) {
let list = []
for(let key in params) {
list.push(`${key}=${params[key]}`)
}
return list.join('&')
}
// 使用
jsonp({
url: 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su', // ------>> 这是百度搜索的接口
params: {wd: "b"},
cb: 'show'
})
.then(res => console.log(res))
CORS
- CORS, 就是让后台设置一个白名单, 白名单里的网站可以跨域
- 实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。
- CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。
nginx
websokit
postMessage
网站a的client无法直接获取网站b的server的数据网站b的client可以直接获取网站b的server的数据- 可以用
<iframe>将网站b的client嵌入到网站a的client中 - 此时两个client页面可以实现通信
- 那么网站b的页面就可以将它获取到的所有后台数据发送给网站a的页面
网站A的页面
<body>
<iframe src="https://bbb.com" frameborder='0' id="iframe" onload="load()"></iframe>
<script>
function load() {
let iframe = document.getElementById('iframe')
iframe.contentWindow.postMessage('把数据给我', "https://bbb.com") // 页面A向页面B发送消息
window.onmessage = function(e) {
console.log('获取到的数据为', e.data)
} // 页面A接收页消息
}
</script>
</body>
网站B的页面
<script>
window.onmessage = function(e) {
console.log(e.data)
e.source.postMessage('info', e.origin)
} // 页面B接收消息, 并将info放送出去
</script>
document.domain
该方式只能用于二级域名相同的情况下,比如 a.test.com 和 b.test.com 适用于该方式。
只需要给页面添加 document.domain = 'test.com' 表示二级域名都相同就可以实现跨域