前端开发中免不了遇到跨域问题,总结下跨域的8种方式
1.代理
同源策略是针对浏览器端进行的限制,可以通过服务器端来解决该问题
2.图片ping或script标签跨域
通过图像Ping,浏览器得不到任何具体的数据,但通过侦听load和error事件,它能知道响应是什么时候接收到的。
图像Ping最常用于跟踪用户点页面或动态广告曝光次数。图像Ping有两个主要的缺点,一是只能发送GET请求,二是无法访问服务器的响应文本。因此,图像Ping只能用于浏览器与服务器间的单向通信。我们将图片的 src 属性指向请求的地址,通过监听img load 和 error 事件,就能知道响应什么时候接受了,响应的数据可以是任意内容,但通常是像素图或204响应。
script标签可以得到从其他来源数据,这也是JSONP依赖的根据。
3.JSONP跨域
JSONP(JSON with Padding)是数据格式JSON的一种“使用模式”
利用 script 开放策略,网页可以得到从其他来源动态产生的 JSON 数据,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript
jquery的jsonp跨域
<script type="text/javascript">
function getResult(data){
alert("through jsonp,receive data from other domain : "+data.result);
}
function jsonp_fun(){
$.ajax({
url:'http://localhost:8888/other/other.jsp',
type:'post',//Jsonp的请求只能是get,虽然在上面演示中,我设置的type为post,但是实际上发的请求还是get
data:{'params':'fromjsonp'},
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:"getResult",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以不写这个参数,jQuery会自动为你处理数据
success: function(data){
},
error: function(){
alert('fail');
}
});
}
</script>
<body>
<input type="button" value="jsonp" onclick="jsonp_fun()"/>
</body>
*参考文章JSONP跨域
https://blog.csdn.net/saytime/article/details/51540876
4.CORS
CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。
关键在于后台设置Access-Control-Allow-Origin: http://api.xxx.com 表示允许访问的域名
跨域请求默认不会携带Cookie信息
5.window.name + iframe
window.name通过在iframe(一般动态创建)中加载跨域HTML文件来起作用。
然后,HTML文件将传递给请求者的字符串内容赋值给window.name,请求者可以检索window.name值作为响应。
iframe标签的跨域能力
window.name属性值在文档刷新后依旧存在的能力(且最大允许2M左右)
contentWindow属性返回iframe元素的Window对象。你可以使用这个Window对象来访问iframe的文档及其内部DOM。
// localhost:8080
<script>
var iframe = document.createElement('iframe');
iframe.style.display = 'none'; // 隐藏
var state = 0; // 防止页面无限刷新
iframe.onload = function() {
if(state === 1) {
console.log(JSON.parse(iframe.contentWindow.name));
// 清除创建的iframe
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
document.body.removeChild(iframe);
} else if(state === 0) {
state = 1;
// 加载完成,指向当前域,防止错误(proxy.html为空白页面)
iframe.contentWindow.location = 'http://localhost:8080/proxy.html'; //重新设置后导致页面不断刷新,所以通过state来控制
}
};
iframe.src = 'http://localhost:8081';
document.body.appendChild(iframe);
</script>
//localhost:8081
<script>
window.name = JSON.stringify({a: 1, b: 2});
</script>
6.window.postMessage()
HTML5新特性,可以用来向其他所有的 window 对象发送消息
7.修改document.domain跨子域
前提条件:这两个域名必须属于同一个基础域名,而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域,所以只能跨子域
例如:www.aaa.com 可以把domain设置为 xxx.com
8.WebSocket
WebSocket protocol 是HTML5一种新的协议,实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。同时允许跨域通讯
WebSocket对象不支持DOM 2级事件侦听器,必须使用DOM 0级语法分别定义各个事件。