// jsonp是解决跨域的一种方法,它利用script标签中的src访问不同源的数据不受同源策略的限制,在src的值中包裹了一个回调函数名,服务器接收到该请求后向该回调函数封装客户端所要请求的数据,由客户端定义的处理函数来处理接收到的收据
// options的数据结构为:
// {
// url:必填-->请求的路径
// data:可填-->请求的参数
// success:必填-->接收到服务器返回的数据的处理函数
// }
function jsonp(options) {
// 动态创建script标签
var script = document.createElement('script');
// 若在同个页面中有多个请求调用jsonp方法,则可能会发生后一个jsonp的fnName覆盖掉前一个jsonp的fnName,所以需要让每一个fnName的名字不同
var fnName = 'jsonp' + Math.random().toString().replace('.', '');
// 因为jsonp是get请求方式,所以将data中的参数拼接成字符串格式
var params = createParams(options.data);
// 将script标签的src值补全
script.src = options.url + '?callback=' + fnName + params;
// 因为回调函数的处理函数必须是全局函数,所以在window上定义一个属性(callback)等于options中自定义的success处理函数
window[fnName] = options.success;
// 将该script标签添加到页面中
document.body.appendChild(script);
// 当script加载完后,它已经完成了请求数据的任务,将其移除页面
script.onload = function() {
document.body.removeChild(script);
}
}
// 将参数拼接成字符串的形式
function createParams(data) {
if (typeof data == 'object') {
var params = '';
for (var key in data) {
params += '&' + key + '=' + data[key];
}
return params;
} else {
return data;
}
}
完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn">点击发送请求</button>
<script type="text/javascript">
var btn = document.getElementById('btn');
btn.onclick = function() {
// // 动态创建script标签,用于jsonp跨域请求
// var script = document.createElement('script');
// script.src = "http://localhost:3001/test?callback=fn";
// // 在页面中添加该script标签
// document.body.appendChild(script);
// // 在该script标签加载完毕后,将其删除,不然每次点击,就会创建新的script标签
// script.onload = function() {
// document.body.removeChild(script);
// }
jsonp({
url: 'http://localhost:3001/jsonp',
data: {
name: 'zsw',
age: 18
},
success: function(data) {
console.log(data);
}
})
}
// jsonp是解决跨域的一种方法,它利用script标签中的src访问不同源的数据不受同源策略的限制,在src的值中包裹了一个回调函数名,服务器接收到该请求后向该回调函数封装客户端所要请求的数据,由客户端定义的处理函数来处理接收到的收据
// options的数据结构为:
// {
// url:必填-->请求的路径
// data:可填-->请求的参数
// success:必填-->接收到服务器返回的数据的处理函数
// }
function jsonp(options) {
// 动态创建script标签
var script = document.createElement('script');
// 若在同个页面中有多个请求调用jsonp方法,则可能会发生后一个jsonp的fnName覆盖掉前一个jsonp的fnName,所以需要让每一个fnName的名字不同
var fnName = 'jsonp' + Math.random().toString().replace('.', '');
// 因为jsonp是get请求方式,所以将data中的参数拼接成字符串格式
var params = createParams(options.data);
// 将script标签的src值补全
script.src = options.url + '?callback=' + fnName + params;
// 因为回调函数的处理函数必须是全局函数,所以在window上定义一个属性(callback)等于options中自定义的success处理函数
window[fnName] = options.success;
// 将该script标签添加到页面中
document.body.appendChild(script);
// 当script加载完后,它已经完成了请求数据的任务,将其移除页面
script.onload = function() {
document.body.removeChild(script);
}
}
// 将参数拼接成字符串的形式
function createParams(data) {
if (typeof data == 'object') {
var params = '';
for (var key in data) {
params += '&' + key + '=' + data[key];
}
return params;
} else {
return data;
}
}
</script>
</body>
</html>