跨域
2019-12-24 本文已影响0人
行走的蛋白质
- 什么是跨域,为什么浏览器要使用同源策略,你有几种方法可以解决跨域问题,了解预检请求吗?
-
浏览器处于安全考虑有同源策略,如果协议、域名、端口有一个不同就是跨域
-
如果没有同源策略的限制存在
浏览器中的 cookie 等其他数据可以任意读取
不同域名下的 DOM 可以任意操作
ajax 可以任意请求其他网站的数据,会泄漏隐私 -
解决跨域的方法
- JSONP 利用 script 标签没有跨域限制的漏洞 完整代码请戳跨域之 jsonp
url 中的 callback 函数名是需要前后端一致的,前端定义函数,后端返回执行函数,参数中携带数据
const jsonp02 = ({url, params, callback}) => {
return new Promise((resolve, reject) => {
let script = document.createElement('script')
params = {...params, callback}
let arr = []
for(let key in params) {
arr.push(`${key}=${params[key]}`)
}
script.src=`${url}?${arr.join('&')}`
document.body.appendChild(script)
window[callback] = (data) => {
resolve(data)
}
})
}
jsonp02({
url: 'http://localhost:8088/jsonp02',
params: {
param02: 'bbb'
},
callback: 'jsonp02cb'
}).then(data => {
console.log('jsonp02:', data)
})
缺点:只能是 get 请求,不安全
-
cors 需要前端和后端同时实现,IE 8 9 需要通过 XDomainRequest 来实现
浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。
服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。 -
document.domain
只适用于二级域名相同的情况下:a.test.com b.test.com
只需要给双方页面设置 document.domain = 'test.com' 即可进行跨域 -
通过 window.name 实现跨域数据的传输
-
PostMessage 常用于获取嵌入页面的第三方数据 完整代码请戳跨域之postMessage
// 发送端
<body>
<div>a.html</div>
<iframe src="http://localhost:8082/b.html" frameborder="0" id="ifram" onload="load()"></iframe>
<script>
function load() {
let ifram = document.getElementById('ifram')
ifram.contentWindow.postMessage('a.html', 'http://localhost:8082')
window.onmessage = function(e) {
console.log(e.data)
}
}
</script>
</body>
// 接收端
<body>
<div>b.html</div>
<script>
window.onmessage = function(e) {
console.log(e.data)
e.source.postMessage('b.html', e.origin)
}
</script>
</body>
6.hash 跨域
a 和 b 是同域, c 跨域,a 用 iframe 嵌套 c 通过 hash 传值,c 收到后同样通过 iframe 嵌套 b 通过 hash 传值,b 中可以用 window.parent.parent.location.hash = location.hash 将 c 的值传回给 a
// window.parent --- c
// window.parent.parent --- a
7.websocket 完整 demo 示例请戳这里