JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而 HTML 的<script> 元素是一个例外。利用 <script> 元素的这个开放策略(导入<script src="http://A.com">src的内容可以不是本网站的即跨域的),网页可以得到从其他来源动态产生的 JSON 资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。
分析1:由标红2可看出 server端需要返回的应该是个js方法而不是json(即callback方法),既然是方法就该满足js方法格式: jsonpcallback(tmp) .
返回的实例 jsonpcallback({"Email":"zhww@outlook.com","Remark":"我来自遥远的东方"})
{"Email":"zhww@outlook.com","Remark":"我来自遥远的东方"}即为需要的json字符串 以参数的形式返回。
给一个实例 访问服务器的登陆返回成功或失败
<script> var dataCollect = { jsonp:function(url,success,error){//定义一个变量dataCollect里面有个json的属性,json是一个方法类型的属性 var flag = false;//用于标识是否成功返回 var call = "p"+new Date().getTime()+Math.round(Math.random()*100);//为callback方法生成方法名 url+="&callback="+call; //将callback参数拼接到url 后台需要定义个String callback接收 window[ call ] = function( tmp ) { //定义(并未调用)回调方法 window[]是将call这个方法变成js全局方法,否则调用时会报错 tmp为返回的json flag = true; if(success)success(tmp); //如果传入了success方法 调用 window[ call ] = undefined; //销毁js全局方法 try { delete window[ call ]; } catch(e) {} //删除 if ( head ) { head.removeChild( script ); } //将script从hred移除 }; var head = document.getElementsByTagName("head")[0] || document.documentElement; //获取head var script = document.createElement("script"); //创建script标签 script.src = url; //给标签一个src 值为url head.insertBefore( script, head.firstChild ); //将标签插入head里面 script就会加载 if(error){ //定义(并未调用有error参数传入时才定义)错误时执行函数 window[ call+"_err" ] = function(){ if(!flag && error)error(); //flag==false才执行即call没被执行时 window[ call+"_err" ] = undefined; try { delete window[ call+"_err" ]; } catch(e) {} window[ call ] = undefined; try { delete window[ call ]; } catch(e) {} if ( head ) { head.removeChild( script ); } }; setTimeout("if("+call+"_err)"+call+"_err();",4000); //如果有错误函数定义 延时4s执行 } return window[ call ]; //返回回调函数 不必须的 },
}
</script>
<script>
var url="http://localhost:8080/项目名/login/checkUser3?username=1&password=1";
dataCollect.jsonp(url,
function (tmp) {console.log(tmp);alert(tmp); },//传入success函数
function () {alert("并没有成功回调或者请求超时");}//传入error函数
); </script>
Server端Java代码
@ResponseBody @RequestMapping("/login/checkUser3") public String checkUser3(String callback,String username, String password,HttpServletRequest request, HttpServletResponse response) throws Exception { //do something return callback+"("+{"resultcode":"0","resultMessage":"成功"}+")"; }