目录:
- 一:为什么会存在跨域问题?
- 二:有哪些常见的跨域问题
- 三:有哪些常见的跨域解决方案?
一:为什么会存在跨域问题?
一句话:大家都知道的 “浏览器同源策略” 导致的,防止跨域资源的访问,很显然,这样是更安全的,要不然,大家都可以访问淘宝的接口,支付宝的接口,那不乱套了。
二:有哪些常见的跨域问题?
- cookie,localstory,indexdb无法跨域共享
- dom无法跨域获取和操作(iframe嵌套不同域名的页面会常出现)
- ajax无法跨域请求
三:有哪些常见的跨域解决方案?
首先这里明确一个概念,不同的跨域问题,需要使用不同的解决方案,而不是我们传统印象中的,跨域问题就只有jsonp,cors等等,这些也只是针对ajax请求跨域问题的解决方案,那其他跨域问题呢?
- 1: cookie,localstory,indexdb跨域共享问题
- 1: cookie: 如果是一级域名相同,二级域名不同,那么可以采用document.domain去控制。即只要两个二级域名下的document.domain是一致的,那么就可以cookie共享
- iframe问题:例如在url1的页面内要嵌入url2的页面,这个时候,我们通常做法是采用iframe去嵌套url2的页面,这时,如果是父子传递怎么传递数据呢? 1: window.name. 2: url的#hash值. 3: window.postMessage(html5新增方法)三者都需要去舰艇其变化,然后获取相应的值。 具体请看,参考文档
- 2: ajax请求跨域问题
- jsonp(动态生成javascript标签,传入callback,后端通过参数返回一段可执行的代码)
- webSocket(协议本身不存在跨域问题)
- cors (后端设置请求头)
- 设置代理(常用的nginx)
四:实际代码解决案例
1: jsonp案例
动态创建script标签,并且执行src引入的代码
window.xxx = function (value) {
console.log(value)
}
var script = document.createElement('script')
script.src = 'http://x.stuq.com:7001/json?callback=xxx'
document.body.appendChild(script)
后端此时返回的通常是如下格式:一个函数调用表达式
/**/ typeof xxx === 'function' && xxx({msg: "hello world"});
2: window.name.window.postMessage,hash案例
以iframe为例子:
例如:当前页面为http://localhost:8000, 然后嵌入一个src为http://localhost:9000的iframe标签,
var iframe = document.createElement('iframe')
iframe.src = 'localhost:9000/public/hash.html'
document.body.appendChild(iframe)
//方法一:在子iframe中将要传给父页面的参数设置hash,在父页面中动态监听hash变化,从而获取值
子iframe:
var data = '要传的数据';
parent.location.href = `http://localhost:8000#msg=data`
父页面:
window.onhashchange = function () {
console.log(location.hash) //解析hash,然后获取data
}
方法二:同理hash,在子frame中设置window.name, 然后在父组件中使用iframe.contentWindow.name获取相应的值
子iframe:
var data = '要传的数据';
window.name = data;
父页面:
iframe.contentWindow.name 就可以获取子iframe中window.name的值。
方法三:同理hash,在子iframe中触发postMessage事件,并且传入参数,在父页面中监听messasge事件,获取相应的值
子iframe:
var data = '要传的数据';
parent.postMessage(data, '*')
父页面:
window.addEventListener('message', function(e) {
console.log(JSON.parse(e.data))
}, false);
3: cors案例
即在后端代码中设置请求头:
Access-Control-Allow-Origin: *
参考文档: