一、本地模拟跨域环境
修改 C:\Windows\System32\drivers\etc\hosts
文件如下:
127.0.0.1 a.test.com
127.0.0.1 b.test.com
二、跨子域ajax
ajax不允许跨子域(IE9及以下的浏览器不允许,现代浏览器可以),但iframe可以,通过iframe协助完成跨子域操作。
<iframe id="bfrm" style="display:none;" src="http://b.test.com/cross_sub_domain.html"></iframe>
// 当前域的请求,IE不支持window.frames['bfrm'].contentWindow
function crossSubDomain() {
document.domain = 'test.com'; // 提升域,关键点
window.frames['bfrm'].contentWindow.doAjax(function(data) {
alert(data);
});
}
// iframe另一个子域的代码
<script>
document.domain = 'test.com';
function doAjax(callback) {
$.ajax('/test').done(function(data) {
callback(data);
});
}
</script>
三、jsonp
原理:
本质并不是ajax,只是 执行了跨域js 。
html中,所有带src属性的标签都可以跨域,script、img、iframe,所以,可以通过script加载其它域的一段动态脚本,这段脚本包含了想要的数据信息。
// 原生js编写
function jsonp(url, data, callback) {
var script = document.createElement('script');
document.body.appendChild(script);
data = data || {};
data.callback = 'cb' + new Date().getTime();
window[data.callback] = callback;
url += '?' + $.param(data);
script.src = url;
script.onload = function () {
document.body.removeChild(script);
}
}
function calltest() {
jsonp('http://b.test.com/testjsonp2', {test: 'ok'}, function (data) {
console.log(data);
});
}
// jQuery中对jsonp的支持通过$.getJSON 来完成。“?callback=?”不可少,callback名称可以是其他名字,jQuery_时间戳
function testGetJson() {
$.getJSON('http://b.test.com/testjsonp2?callback=?', {test: 'ok'}, function(data) {
console.log(data);
});
}
// 通过$.Ajax支持1,请求内容http://b.test.com/testjsonp2?callback=jQuery1113030788393518155766_1492399262805&_=1492399262826
function testAjaxJsonp() {
$.ajax('http://b.test.com/testjsonp2?callback=?', {
dataType: 'jsonp'
}).done(function(data) {
console.log(data);
});
}
// 通过$.Ajax支持2,其中的参数jsonp、jsonpCallback、cache对应上面的?callback?,只是此处是自定义的内容——http://b.test.com/testjsonp3?cbname=cbfun
function testArgs() {
$.ajax('http://b.test.com/testjsonp3', {
dataType: 'jsonp',
jsonp: 'cbname',
jsonpCallback: 'cbfun',
cache: true,
success: function(data) {
console.log(data);
}
});
}
jsonp的缺点:
- 只支持get方式;
- 后端代码要调整。
四、CROS 跨域资源共享(服务器设置响应头信息)
原理:
xhr level2 支持的新标准,允许发起ajax请求,但是为了跨域安全,需要在服务器响应头部提供一些信息,供浏览器校验请求是否被允许。
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "test");
res.header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE");
next();
});
CORS头信息通用设置方法:
http://enable-cors.org/server.html