首先说下同源,同源策略是浏览器的一种安全策略,所谓同源是指:域名、协议、端口完全相同。而跨域就是不同源!一般 a, img, link, video, audio, 等等能够发出请求的标签都可以实现跨域访问。但是这些标签不能得到返回的东西,所以一般不会用他们来请求资源。

跨域方法

原生 JavaScript 跨域

1
2
3
4
5
6
7
8
<script type="text/javascript">
function showuser(data) {
var data = JSON.parse(data);
console.log(data);// 处理得到的 data
};
</script>

<script src="http://x.cn/showalluser.html?callback=showuser" charset="utf-8"></script>

jQuery 跨域

1
2
3
4
5
6
7
8
9
$.ajax({
type: "post",
url: "http://127.0.0.1:8080/showalluser.html",
dataType: "jsonp",
jsonp: "callback",
success: function(data) {
console.log(data);// 处理得到的 data
}
});

iframe 跨域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function(URL, callBack) {
$iframe = $("<iframe style='display: none;'></iframe>");
$iframe.prop("src", URL);
$("body").append($iframe);

$iframe.on('load', function() {
// 转换成 jsonStr
// contentDocument是 iframe 节点的方法获取contentDocument
var ifrDocument = this.contentDocument;

var jsonStr = $(ifrDocument).find("body").text();

// 转换成 json 对象
var jsonObj = JSON.parse(jsonStr);

// 把 json 对象传给回调函数
callBack(jsonObj);
// 删除当前的 iframe
$(this).remove();
});
}

原生 JavaScript 跨域封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<script>
// 封装数据 跨域url params fn
function crossDomain(url,params,fn){
var head = document.getElementsByTagName('head')[0];
// 1. 处理回调函数
var cbName = 'jsonp'+
(Math.random() * Math.random()).toString().substr(2) +
new Date().getTime();
// 将回调函数挂载到 window 对象上
window[cbName] = function(data){
// 拿到并处理数据,交给回调函数
fn(data);
// 拿到数据后remove掉
//head.removeChild(scriptObj);
}
// 2. 解析url,处理查询字符串 解决这样的需求 ?count=5
var qstring = '';
for(var key in params){
qstring += key + '=' + params[key] + '&';
}
qstring += 'callback=' + cbName;
url += '?' + qstring;
// 3. 插入script
var scriptObj = document.createElement('script');
scriptObj.src = url;
head.appendChild(scriptObj);
}
</script>

<script>
// 使用
crossDomain('http://api.douban.com/v2/movie/in_theaters',{},function(data){
console.log(data);
})
</script>
1
2
3
4
<!-- 解读:注意上面封装的函数会在 head 标签生成下面的内容,并随机产生函数名防止冲突 -->
<script src="jsonp412964552676679031484646377133(data)”>// 挂载在 window 上可以直接执行
/*远程获取的 data 传入 jsonp* 函数内容,交给回调函数fn(data) */
</script>