原生JSONP实现_动态加载js(利用script标签)

      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":"[email protected]","Remark":"我来自遥远的东方"})

     {"Email":"[email protected]","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":"成功"}+")";
}

猜你喜欢

转载自blog.csdn.net/liwb94/article/details/80221224