在解释JSONP之前,我们需要了解下 ”同源策略“ 这个概念,这对理解跨域有帮助。基于安全的原因,浏览器是存在同源策略机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载额文档的属性。有点绕,说的简单点就是浏览器限制脚本只能和同协议、同域名、同端口的脚本进行交互。
JSONP就是为了解决这一问题的,JSONP是英文JSON with Padding的缩写,是一个非官方的协议。他允许服务端生成script tags返回值客户端,通过javascript callback的形式来实现站点访问。JSONP是一种script tag的注入,将server返回的response添加到页面是实现特定功能。
简而言之,JSONP本身不是复杂的东西,就是通过scirpt标签对javascript文档的动态解析绕过了浏览器的同源策略。
jQuery对跨域请求有两种解决方案分别是jQuery的jquery.ajax jsonp格式和jquery.getScript方式
。
首先介绍下$.ajax的参数
type:请求方式 GET/POST
url:请求地址
async:布尔类型,默认为true 表示请求是否为异步,如果为false表示为同步。
dataType:返回的数据类型
jsonp:传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success:调用成功执行的函数
error:异常处理函数
JSONP原理及实现
接下来,来实际模拟一个跨域请求的解决方案。后端为Spring MVC架构的,前端则通过Ajax进行跨域访问。
1、首先客户端需要注册一个callback(服务端通过该callback(jsonp)可以得到js函数名(jsonpCallback)),然后以JavaScript语法的方式,生成一个function
2、接下来,将JSON数据直接以入参的方式,放置到function中,这样就生成了一段js语法文档,返回给客户端。
3、最后客户端浏览器动态的解析script标签,并执行返回的JavaScript语法文档片段,此时数据作为参数传入到了预先定义好的
回调函数里(动态执行回调函数)。
这种动态解析js文档和eval函数是类似的。
接下来就是如何实现了,客户端代码。
注解:jsonp会创建一个查询字符串参数callback=?,这个参数会加载请求的URL后面,服务端应当在JSON数据前加上回调函数名,以便完成一个JSONP请求。也就是说服务器端需要对返回的数据做处理,格式为如下形式:
jsonpCallback(<{ name:"html580.com"}>)
接下来看服务器端针对上述代码的处理:
前端Ajax跨域请求触发之后,能够有效的得到JSON数据,情况如下:
至此,Ajax跨域请求也已经解决了,不过还是有两点地方需要注意:
1、没有关于JSONP调用的错误处理,动态插入的脚本有效,则执行调用,无效就默默失败(无任何提示)。
JSONP就是为了解决这一问题的,JSONP是英文JSON with Padding的缩写,是一个非官方的协议。他允许服务端生成script tags返回值客户端,通过javascript callback的形式来实现站点访问。JSONP是一种script tag的注入,将server返回的response添加到页面是实现特定功能。
简而言之,JSONP本身不是复杂的东西,就是通过scirpt标签对javascript文档的动态解析绕过了浏览器的同源策略。
jQuery对跨域请求有两种解决方案分别是jQuery的jquery.ajax jsonp格式和jquery.getScript方式
。
首先介绍下$.ajax的参数
type:请求方式 GET/POST
url:请求地址
async:布尔类型,默认为true 表示请求是否为异步,如果为false表示为同步。
dataType:返回的数据类型
jsonp:传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success:调用成功执行的函数
error:异常处理函数
JSONP原理及实现
接下来,来实际模拟一个跨域请求的解决方案。后端为Spring MVC架构的,前端则通过Ajax进行跨域访问。
1、首先客户端需要注册一个callback(服务端通过该callback(jsonp)可以得到js函数名(jsonpCallback)),然后以JavaScript语法的方式,生成一个function
2、接下来,将JSON数据直接以入参的方式,放置到function中,这样就生成了一段js语法文档,返回给客户端。
3、最后客户端浏览器动态的解析script标签,并执行返回的JavaScript语法文档片段,此时数据作为参数传入到了预先定义好的
回调函数里(动态执行回调函数)。
这种动态解析js文档和eval函数是类似的。
接下来就是如何实现了,客户端代码。
$.ajax({
type: "get",
async: false,
url: "http://localhost:8080/html580/get",
dataType: "jsonp",
jsonp: "callback", //服务端用于接收callback调用的function名的参数
jsonpCallback: "jsonpCallback", //callback的function名称,服务端会把名称和data一起传递回来
success: function(json) {
alert(json<0>.name);
}
});
注解:jsonp会创建一个查询字符串参数callback=?,这个参数会加载请求的URL后面,服务端应当在JSON数据前加上回调函数名,以便完成一个JSONP请求。也就是说服务器端需要对返回的数据做处理,格式为如下形式:
jsonpCallback(<{ name:"html580.com"}>)
接下来看服务器端针对上述代码的处理:
@RequestMapping("/get")
public void get(HttpServletRequest req,HttpServletResponse res) {
res.setContentType("text/plain");
String callbackFunName =req.getParameter("callback");//得到js函数名称
try {
res.getWriter().write(callbackFunName + "(< { name:\"html580.com\"}>)"); //返回jsonp数据
} catch (IOException e) {
e.printStackTrace();
}
}
前端Ajax跨域请求触发之后,能够有效的得到JSON数据,情况如下:
至此,Ajax跨域请求也已经解决了,不过还是有两点地方需要注意:
1、没有关于JSONP调用的错误处理,动态插入的脚本有效,则执行调用,无效就默默失败(无任何提示)。
2、JSONP被不信任的服务使用会有一定的安全隐患,不信任的服务提供的脚本是恶意的。
转载地址:http://www.html580.com/study/229.html