什么是跨域?
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源
同源策略即:同一协议,同一域名,同一端口号。当其中一个不满足时,我们的请求即会发生跨域问题。
同源策略限制以下几种行为:
1、Cookie、LocalStorage 和 IndexDB 无法读取
2、 DOM 和 Js对象无法获得
3、 AJAX 请求不能发送
常见跨域场景
URL 说明 是否允许通信
http://www.8083.com/a.js
http://www.8083.com/b.js 同一域名,不同文件或路径 允许
http://www.8083.com/lab/c.js
http://www.8083.com:8000/a.js
http://www.8083.com/b.js 同一域名,不同端口 不允许
http://www.8083.com/a.js
https://www.8083.com/b.js 同一域名,不同协议 不允许
http://www.8083.com/a.js
http://127.0.0.1/b.js 域名和域名对应相同ip 不允许
http://www.8083.com/a.js
http://x.8083.com/b.js 主域相同,子域不同 不允许
http://8083.com/c.js
http://www.8082.com/a.js
http://www.8081.com/b.js 不同域名 不允许
跨域解决方案
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域
一、 通过jsonp跨域
通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。
1、原生实现:
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传参并指定回调执行函数为onBack
script.src = 'http://www.demo2.com:8080/login?user=admin&callback=onBack';
document.head.appendChild(script);
// 回调执行函数
function onBack(res) {
alert(JSON.stringify(res));
}
</script>
服务端返回如下(返回时即执行全局函数):
onBack({"status": true, "user": "admin"})
2、jquery ajax:
$.ajax({
url: 'http://www.demo2.com:8080/login',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
jsonpCallback: "onBack", // 自定义回调函数名
data: {}
});
3、vue.js
this.$http.jsonp('http://www.demo2.com:8080/login', {
params: {},
jsonp: 'onBack'
}).then((res) => {
console.log(res);
})
其实jsonp的整个过程就类似于前端声明好一个函数,后端返回执行函数。执行函数参数中携带所需的数据
1、在本地定义一个服务端回调的function函数(服务端调用该函数将查询的数据以参数形式传入这个函数)
2、script包含服务器脚本,里面要将本地定义好的function函数名传过去,获取到数据后调用该函数
3、在异源的地址调用了本地的js函数,然后再function里面对函数进行处理。
jsonp缺点:只能实现get一种请求