跨域:获取不同源的资源时,就属于跨域。源:协议、域名、端口。默认端口是80。三者任一不同就是跨域。
ajax 直接请求跨域的资源时,存在跨域无权限访问的问题。而页面上的引入 js 文件时则不受跨域影响,并且可以发现凡拥有 src
属性的标签,都拥有跨域的能力,比如 <script>
、<img>
、<iframe>
。
而跨域请求 jsonp 正是利用了,<script>
标签的跨域能力。
大致原理
首先在页面中定义一个 handle 函数,然后通过引入的 <script>
,传入参数并执行 handle 函数,传入的参数即页面期望跨域请求拿到的数据。
<!DOCTYPE html>
<html>
<head>
<script>
function handle (data) {
let res = JSON.parse(data);
document.getElementById('result').innerHtml = res.result;
}
</script>
<script src="http://www.xxx.com/test.js"></script>
</head>
<body>
<p>
result is <span id="result"></span>
</p>
</body>
</html>
test.js 文件内容如下:
// test.js
handle({"result": "riverjean"});
简单的 jsonp 实现
动态地创建 script
标签,实现 jsonp 请求:
<!DOCTYPE html>
<html>
<head>
<script>
window.handle = function (data) {
let res = JSON.parse(data);
document.getElementById('result').innerHtml = res.result;
}
function jsonp (url, callback) {
var script = document.createElement('script');
var target = url + '?callback=' + callback;
script.setAttribute(src, target);
document.getElementsByTagName('head')[0].appendChild(script);
}
jsonp('http://www.xxx.com/testjsonp', handle)
</script>
</head>
<body>
<p>
result is <span id="result"></span>
</p>
</body>
</html>
然后服务端会返回一段代码给客户端执行:
handle({"result": "riverjean"});