JSONP解决跨域问题

参考廖雪峰老师的教程 AJAX教程,是用JSONP跨域

这是因为浏览器的同源策略导致的。默认情况下,JavaScript在发送AJAX请求时,URL的域名必须和当前页面完全一致。 完全一致的意思是,域名要相同(www.example.comexample.com不同),协议要相同(httphttps不同),端口号要相同(默认是:80端口,它和:8080就不同)。有的浏览器口子松一点,允许端口不同,大多数浏览器都会严格遵守这个限制。

廖雪峰老师展示了一段代码,使用JSONP(不是json格式!!)从网易上获取证券数据。 然后我就准备自己写一下来完成这个 自己后台写的url如下 'http://www.easy.io/test/test.php?callback=getInfo 数据格式如下,这个返回的数据格式,就是使用回调函数名(JSON数据)

1
getInfo({"uid":"5625","uname":"chris","address":"shanghai"})

返回一个JSONP的数据 观察一下上面这个URL,以?开始分割,后面是callback=getInfo 这里主要是告诉要调用的后台页面传入一个键值对为”callback”=>”getInfo“ 如果用php来完成test.php的代码,代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
//输出格式为json
header('Content-type: application/json');
//得到URL中传入的参数,后面需要将json格式拼接成jsonp的格式。
//拼接形式:函数方法名(json)
//最后输入格式如上
$jsoncallback = htmlspecialchars($_REQUEST['callback']);
$a = array(
"uid"=>'5625',
"uname"=>"chris",
"address"=>'shanghai'
);
echo $jsoncallback."(".json_encode($a).")";

前端调用jsonp,HTML中通过onclick出发getSelf()方法,能够调用getSelf()加载javascript,然后跨域加载数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getSelf() {
var
js = document.createElement('script'),
head = document.getElementsByTagName('head')[0];
js.src = 'http://www.easy.io/test/test.php?callback=getInfo';
head.appendChild(js);
}
function getInfo(data) {
var p = document.getElementById('self-jsonp');
p.innerHTML = 'id:'+data.uid+"<br/>"
+'name:'+data.uname+"<br/>"
+'address:'+data.address+"<br/>"
;
}

完整代码如下:

index.html

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
36
37
38
39
40
41
42
43
44
45
46
47
48
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="wy-jsonp"></div>
<input type="submit"value="获取网易" onclick="getPrice()">
<div id="self-jsonp"></div>
<input type="submit"value="获取自己" onclick="getSelf()">
</body>
<script>
'use strict';
function refreshPrice(data) {
var p = document.getElementById('wy-jsonp');
p.innerHTML = '当前价格:' +
data['0000001'].name +': ' +
data['0000001'].price + ';' +
data['1399001'].name + ': ' +
data['1399001'].price;
}

function getInfo(data) {
var p = document.getElementById('self-jsonp');
p.innerHTML = 'id:'+data.uid+"<br/>"
+'name:'+data.uname+"<br/>"
+'address:'+data.address+"<br/>"
;
}

function getPrice() {
var
js = document.createElement('script'),
head = document.getElementsByTagName('head')[0];
js.src = 'http://api.money.126.net/data/feed/0000001,1399001?callback=refreshPrice';
head.appendChild(js);
}

function getSelf() {
var
js = document.createElement('script'),
head = document.getElementsByTagName('head')[0];
js.src = 'http://www.easy.io/test/test.php?callback=getInfo';
head.appendChild(js);
}
</script>
</html>
1
2
3
4
5
6
7
8
9
10
<?php
header('Content-type: application/json');
$jsoncallback = htmlspecialchars($_REQUEST['callback']);
$a = array(
"uid"=>'562586060',
"uname"=>"chris",
"address"=>'shanghai'
);
echo $jsoncallback."(".json_encode($a).")";

最后展示: img