详细分析jsonp的原理和实现
针对跨领域的问题,本文主要详细分析jsonp的原理,希望能给大家提供帮助。
详细分析了jsonp的原理和实现
1.跨领域问题。
二,跨域的原因
Js不是跨域请求。出于安全原因,js不能跨域设计。
什么是跨域:
1.当域名不同时。
2.域名相同,但端口不同。
只有域名和端口相同时才能访问。
您可以使用jsonp来解决跨域问题。
三、跨域失败案例3.1、同源策略
首先,出于安全考虑,浏览器具有同源策略机制,防止从一个来源加载的文档或脚本获取或设置从另一个来源加载的文档的属性。我好像不知道是什么意思,只是练习一下。
3.2,只需构建两个网页
一个端口是2698,另一个是2701,根据定义,这两个端口的来源不同。
3.3.使用jQuery启动来自不同来源的请求
在端口为2698的网页上添加一个按钮,Click事件随机向端口为2701的域发起两个请求。
$('#getOtherDomainThings ')。单击(function () {$)。get(' http://localhost :2701/Scripts/jquery-1 . 4 . 4 . min . js ',函数(数据){console.log(数据)})$。get(' http://localhost :2701/home/index ',函数(数据){console.log(数据)})})
按照同源策略,显然会悲剧。浏览器将阻止该请求,并且根本不会启动它。(访问控制-允许-来源不允许)
好吧,原来jsonp就是为了解决这个问题。
换句话说,另一个项目的json数据直接在src或url中请求。
例如,在一个端口为8080的项目中的一个页面的url中,直接请求一个http://localhost 33608081/category.json的语句,而这个category . JSON在8081 webapp的目录中,会导致跨域请求的提示。
四,跨领域解决方案4.1,启示
有时我们经常在项目中看到这样的代码
脚本类型=' text/JavaScript ' src=' http :3359 com/habe/weixin/js/jquery . js '/脚本,所以即使不在同一个项目中也可以请求成功。就是利用这个漏洞,或者说技术,来达到这个大方的要求。
4.2,方法(案例1) 4.2.1,使用脚本从不同来源获取json
既然叫jsonp,很明显目的就是json,是跨域获取。根据上面的分析,很容易想到:用js构造一个脚本标签,将json url分配给脚本的scr属性,将这个脚本插入dom,让浏览器获取。练习:
函数create script(src){ $(' script//script ')。attr('src ',src)。附录(正文)
添加要测试的按钮事件:
$('#getOtherDomainJson ')。单击(function () { $)。get(' http://localhost :2701/home/some JSON ',function(data){ console . log(data)})})
首先第一个浏览器的Url,http://localhost :2701/home/some json确实有一个JSON,在2698网页上用脚本标签请求这个2701的Url也是200OK的,但是有报道说底部js语法错误。最初,在加载脚本标记后,响应将立即作为js执行。显然,{'email' :' [email protected]','备注' : '我来自远东' }都不是合法的js语句。
4.2.2、使用脚本获取国外jsonp
显然,将上面的json放入回调方法是最简单的方法。比如,变成这样:
如果有jsoncallback的方法,那么jsoncallback({ ' email ' : '[email protected]','备注' : '我来自远东' })就是合法的js语句。
这里需要注意的是,原json格式数据{'email' :' [email protected]','备注' : '我来自远东' }应该打包为JSONP回调({'email' 3360' [email protected]','备注' : '我来自远方。
因为服务器不知道客户端的回调是什么,所以硬代码不可能是jsonpcallback,所以需要一个QueryString让客户端告诉服务器回调方法是什么。当然,QueryString的关键要符合服务器的协议,上面是“回调”。
添加回调函数:
函数jsonp回调(JSON) {console.log (JSON)}稍微改变了前面方法的参数:
$(' # getjsonbyhand ')。单击(function(){ Createscript(' http://localhost :2701/home/somejsonp?回调=jsoncallback’)})
200OK,服务器返回jsoncallback({ ' email ' : '[email protected]','备注' : '我来自远东' }),我们也写了jsoncallback方法,当然会执行。OK成功获得json。是的,这是整个jsonp。
4.2.3.使用jQuery获取jsonp
在上面的方法中,插入脚本标签和定义回调有点麻烦。您可以通过使用jQuery直接获得所需的json数据,这与上面的jsonp相同:
$(' # GetJSonBYjquery ')。单击(function () {$)。Ajax({ URL : ' http://localhost :2701/home/somejsonp ',dataType: 'jsonp ',jsonp: 'callback ',success:函数(data) {console.log (data)}}得到的结果与上面类似。
4.2.4总结
总之,脚本标签是用来绕过同源策略,得到这样一个数据的。jsonpcallback是页面存在的回调方法,参数是想要的json。
Jsonp回调({'email' :' [email protected]','备注' : '我来自远东' })
4.3,案例2,4.3.1,简单应用
程序a中样本的部分代码:
脚本类型='text/javascript'//回调函数回调(data){ alert(data . message);}/script脚本类型=' text/JavaScript ' src=' http :3358 localhost 336020002/test.js '/脚本程序b中test . js的代码:1 //调用回调函数,以json数据形式作为解释传递,完成回调2 callback({ message : ' success ' })这其实是JSONP的简单实现方式,或者JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数
用JSON数据填充回调函数,这就是JSONP的JSON Padding的意思。
一般来说,我们希望这个脚本标签可以动态调用,而不是不等待页面显示就执行,因为它在html中如上所述是固定的,非常不灵活。我们可以通过javascript动态创建脚本标签,这样就可以灵活调用远程服务。
4.3.2.用一个升级简单的应用程序
程序a中样本的部分代码:
脚本类型='text/javascript '函数回调(数据){ alert(data . message);}//添加脚本标记{ var script=document . create element(' script ')的方法函数addscript tag(src);script.setAttribute('type ',' text/JavaScript ');script.src=srcdocument.body.appendChild(脚本);} window . onload=function(){ addScriptTag(' http://localhost :20002/test . js ');}/script程序b的test.js代码保持不变。让我们再次执行程序。和原来的一样吗?如果我们想再次调用远程服务,只需添加addScriptTag方法并传入远程服务的src值。这里解释一下为什么把addScriptTag方法放入window.onload方法中,因为addScriptTag方法中有一句document.body.appendchild(脚本);该脚本标记被添加到正文中。由于我们编写的javascript代码在head标签中,而document.body还没有初始化,所以我们需要先通过window.onload方法初始化页面,这样就不会出错了。
这样可以动态改变http://localhost 336020002/test . js路径。
4.3.3、简单应用的升级二
上面的例子是JSONP最简单的实现模型,但并不是真正的JSONP服务。我们来看看真正的JSONP服务是什么样的,比如谷歌的ajax搜索界面:http://ajax.googleapis.com/ajax/services/search/web? v=1.0q=?回调=?
q=?这个问号表示你要搜索什么,最重要的是第二次回调=?这就像回调函数的名字一样,就是把自己在客户端定义的回调函数的函数名发送到服务器端,服务器端会返回你定义了回调函数名的方法,把得到的json数据传入这个方法完成回调。有点罗嗦,我们来看看实现代码:
脚本类型='text/javascript'//添加脚本标记函数addscripttag (src)的方法{ var script=document . create element(' script ');script.setAttribute('type ',' text/JavaScript ');script.src=srcdocument.body.appendChild(脚本);}window.onload=function(){//搜索apple,并将用户定义的回调函数名结果传入回调参数addscripttag(' http://Ajax . googleapis.com/Ajax/services/search/web?v=1.0q=apple callback=result’);}//自定义回调函数resultfunction result(数据){//我们只需获取url数据警报(data.responsedata.results [0])。转义的URL)在苹果搜索结果的第一条记录中;}/script此结果方法是自定义的。服务器上可能有成千上万个类似于千千结果的回调函数,但是我现在想要的是结果,而不是其他方法,所以我将在这里自己定义回调方法。没有写死。也许下次我会把它改成result1,result2,result3,只需要自己更改回调方法的名称。
4.4.4,jquery对jsonp的支持
jQuery框架当然支持JSONP,您可以使用$。getjson (URL、【数据】、【回调】)方法(详见http://api.jquery.com/jQuery.getJSON/)。然后让我们修改程序a的代码,改用jQuery的getJSON方法(在下面的例子中,我们只编写了getJSON(url,[回调]):
脚本类型=' text/JavaScript ' src=' http :http://code . jquery.com/jquery-latest . js '/script script type=' text/JavaScript ' $。getJSON(' http://localhost :20002/MyServiCe . ashx?回调=?”,function(data){ alert(data.name '是一个a ' data . sex);});/script的结果是一样的。需要注意的是,url后面必须添加一个回调参数,这样getJSON方法就会知道服务是由JSONP访问的,回调后面的问号是内部自动生成的回调函数名。可以调试这个函数名,比如jquery 17207481773362960661 _ 133257548661。
当然,添加我们想要指定我们自己的回调函数名,或者服务指定一个固定的回调函数名。我们可以用美元。ajax方法(参数很多,详情请参考http://api.jquery.com/jQuery.ajax)。让我们先来看看如何实现它:
脚本类型=' text/JavaScript ' src=' http :http://code . jquery.com/jquery-latest . js '/script script type=' text/JavaScript ' $。Ajax({ URL : ' http://localhost :20002/MyServiCe . ashx?回调=?”,dataType:'jsonp ',jsonpCallback: ' person ',success : function(data){ alert(data . name '是a ' a ' data . sex);} });/script正确。jsonpCallback可以指定我们自己的回调方法名person,远程服务接受的回调参数的值不再是自动生成的回调名,而是person。数据类型指定以JSOPN模式访问远程服务。
以上就是这次分享的关于jsonp原理的所有内容和代码。请在下面留言讨论。
版权声明:详细分析jsonp的原理和实现是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。