由于游览器的同源政策的原因,Ajax只能向同源的服务器进行访问,如果访问游览器就会报错,所以使用JSONP解决同源限制问题
jsonp不属于Ajax请求,但它可以模仿Ajax请求
使用方法:
1,在客户端中,将不同源的服务器端请求地址写在script标签的src属性中 <script src='www.xxx.com'></script>
2,但是在服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数,
const data='fn({name:'zhangsan',age:'20'}); res.send(data);
3,在客户端全局作用域下定义函数fn
function fn (data){ }
4,在fn函数内部对服务器端返回的数据进行处理
function fn(data){alert(data);}
下面是对JSONP使用的步骤进行封装,以免每次使用都要去敲那些繁琐的代码
function JSONP(data) {
//对参数进行拼接
var params='';
for(var attr in data.data){
params+='&'+attr+'='+data.data[attr];
}
//创建一个script标签
var script=document.createElement('script');
//给这个script添加src属性,就是你要前往非同源的地址
//由于非同源的服务器端会返回一个方法,这个方法还必须要客户端传过去的
//在请求地址后面还要添加一个回调函数,这个回调函数必须是全局函数,并且不同的请求调用的回调函数可能都不同,所以这个名字要是一个随机的
var fnName='myJsonp'+Math.random().toString().replace(".",'');
window[fnName]=data.success;
script.src=data.url+'?callback='+fnName+params;
//将script追加到页面中
document.body.appendChild(script);
script.onload=function() {
document.body.removeChild(script);
}
}
以上是对客户端的jsonp代码进行封装优化的,接下来在看下服务器端的代码优化
app.get('/jsonp',(req,res)=>{
// //接受客户端传递过来的函数名称
// var fn=req.query.callback;
// //如果要传个客户端的数据是JSON类型的,需要先将其转为字符串,然后与函数调用进行拼接
// //将函数名称对应的函数调用代码返回给客户端
// const result=fn+'({name:"zhangsan"})';
// res.send(result);
//express框架提供了对客户端的jsonp数据处理的方法
res.jsonp({name:'lisi',age:20})
//这一句代码就相当于做了上面所有的操作
});