自己实现一个JsonP

前端之家收集整理的这篇文章主要介绍了自己实现一个JsonP前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在没有XMLHttpRequest lEvel2的时候,我们在使用Ajax的时候要实现客户端@H_404_3@跨域就只能用jsonp。而jsonp的原理很简单,那就是利用了浏览器加载JavaScript和css等资源的时候是允许跨域加载的。

这也是以前黑客经常攻击我cms搭建网站的方式。莫名其妙让我的主页打开以后就跳到其他地方了。有的黑客直接给我写到首页代码里,有的黑客使用script脚本引入的方式。

jsonp的原理:@H_404_3@

说出来很简单,那就是动态创建<script src="你ajax发起GET请求的地址"></script>这个DOM。

这样的话,浏览器就允许script标签请求跨域的内容,但是如何拿到服务端返回的内容并让浏览器端开发人员做点事情呢。

这里用到另一个技巧,很土的办法:那就是让服务端返回的内容就直接是一个函数调用的语法。

比如:服务端返回这样的内容-----> YourFunc({服务端要返回给客户的对象}){}

Demo:YourFunc({"a":1,"b":2})


然后客户端需要提前动态在全局空间内注册一个函数,其名称为YourFunc(data){}. 这样当<script src="ajaxurl"></script>请求返回数据后,浏览器解析其中的内容,会自动执行YourFunc({a:1,b:2}), 这样就调用了你提前注册好的函数YourFunc(data){};

你在全局空间中注册函数可以这样写:YourFunc(rel){ 执行服务器结果处理的事情 }

我的JsonP封装:@H_404_3@

我对Ajax请求的创建和执行进行了函数封装,以方便开发人员使用。ajax请求函数如下:

需要注意的是:在我的ajax函数使用时需要遵循一个约定,那就是服务端返回的数据约定为:

{

"success":true or false,

"errormsg":your logic error,

"data":your data when success,if Failed put it null is ok.

}

//函数形参说明:@H_404_3@

//Ajax请求实现跨域(jsonP因为其实现机制原因故只能是GET请求)@H_404_3@

//url-----,字符串,用户要ajax请求的URL@H_404_3@

//callbackName,字符串,设置一个回调函数名。您只需要保证服务器端使用同名函数来包装json对象即可。@H_404_3@一般服务器端可以类似于这样设置: response.write($Request['callback']+"({json对象})"),可保证与客户端设置一致。@H_404_3@

//onsuccessfun,函数对象,表示请求成功后要执行的回调。(200状态码,且json状态为success)@H_404_3@

//onlogicError,函数对象,表示请求的逻辑失败后的回调。(也是200状态码,但json状态为fail)@H_404_3@


@H_404_3@

function ajaxjsonp(url,callbackName,onsuccessfun,onlogicError) {@H_404_3@

//提前创建好回调函数@H_404_3@

window[callbackName] = function (rel) {@H_404_3@

if (rel.success == true) {@H_404_3@

onsuccessfun(rel.data);//调用请求成功的处理函数@H_404_3@

} else {@H_404_3@

onlogicError(rel.errormsg);//调用逻辑错误处理的函数@H_404_3@

}@H_404_3@

};@H_404_3@


@H_404_3@

//构造一个DOM向服务器发请求@H_404_3@

var scriptdom = document.createElement("script");@H_404_3@

var callbackRequest = "callback="+callbackName;@H_404_3@

url = url.indexOf("?")>0?url + "&" + callbackRequest:url+"?"+callbackRequest;@H_404_3@

scriptdom.src = url;//利用DOM向服务器发起GET请求@H_404_3@

document.body.appendChild(scriptdom);@H_404_3@

}@H_404_3@

使用实例:@H_404_3@

当你页面需要使用jsonp跨域的时候,只需要这样调用即可:

CYJLIB.ajaxjsonp("http://localhost:54675/","cyjddcallback",function (data) { document.getElementById("ttt").innerHTML = data.a },function (msg) { document.getElementById("ttt").innerHTML = msg;});

以上语句中CYJLIB请忽略即可,我只是把ajaxjsonp函数放入了一个对象而已。 后面的传参中上文都有介绍,很容易理解。关于callbackName这个参数,只要你服务器像上文那样设置好了,那客户端就可以随意填写。

缺点:@H_404_3@

我写的这个函数无法检测HTTP请求中的错误,也无法获取到请求过程中的状态---比如“正在请求”。

另外,jsonp对服务器来说是有安全危险的,比如任何人都可以用浏览器去调用你的接口,给你带来了流量损耗。

同时,浏览器这种机制(bug)也会让恶意的人利用,当他取得你页面相关权限后,来跨域注入恶意js代码到你的页面

所幸,html5提供的XHR level2解决了这种安全问题。

另送上非跨域请求的ajax包装函数:@H_404_3@

//Ajax请求封装函数@H_404_3@

//GorP,string类型,表示这个ajax请求使用Get还是Post方式@H_404_3@

//欧尼@H_404_3@

function ajax(GorP,url,onprocessfun,onhttpError,onlogicError) {@H_404_3@

//创建考虑兼容性的XMLHttpRequest对象@H_404_3@

var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");@H_404_3@

//打开http连接准备向服务器指定的URL发送post请求(Get请求可能会有缓存问题,所以尽量用post请求)@H_404_3@

xmlhttp.open(GorP,true);@H_404_3@


@H_404_3@

//定义好xmlhttp对象接收到返回状态值时的事件。@H_404_3@

xmlhttp.onreadystatechange = function () {@H_404_3@

if (xmlhttp.readyState == 4) {@H_404_3@

clearTimeout(timer);@H_404_3@

//返回状态码4代表服务端已经完成了返回数据的任务。@H_404_3@

//接下来判断http报文里的状态码@H_404_3@

if (xmlhttp.status == 200) {@H_404_3@

var rel = JSON.parse(xmlhttp.responseText);@H_404_3@

if (rel.success = true) {@H_404_3@

onsuccessfun(rel.data);//调用请求成功的处理函数@H_404_3@

} else {@H_404_3@

onlogicError(rel.errormsg);//调用逻辑错误处理的函数@H_404_3@

}@H_404_3@

}@H_404_3@

}@H_404_3@

}@H_404_3@

//超时处理:放弃xhp请求,并调用onerror函数,把错误码给onerror。@H_404_3@

timer = setTimeout(function () { if (xmlhttp) { xmlhttp.abort(); } onhttpError(xmlhttp.statusText); },20000);@H_404_3@

//上面定义好了xmlhttprequest对象,而且设置了该对象状态变化时的事件。接下来开始发送请求@H_404_3@

xmlhttp.send();@H_404_3@

onprocessfun();@H_404_3@

}@H_404_3@

猜你在找的Json相关文章