Heim >Web-Frontend >js-Tutorial >Beherrschen Sie die Prinzipien und die Implementierung von JSONP vollständig

Beherrschen Sie die Prinzipien und die Implementierung von JSONP vollständig

小云云
小云云Original
2018-01-18 09:32:061794Durchsuche

Bei domänenübergreifenden Problemen analysiert dieser Artikel hauptsächlich die Prinzipien von JSONP im Detail und bietet Ihnen eine detaillierte Analyse der Prinzipien von JSONP sowie eine Zusammenfassung domänenübergreifender Probleme mit Bildern und Texten. Ich hoffe, es kann Ihnen helfen.

Detaillierte Analyse der Prinzipien und Implementierungsmethoden von JSONP

1: Domänenübergreifende Probleme.

Zweitens der Grund für domänenübergreifende

Js können keine domänenübergreifenden Anfragen stellen. Aus Sicherheitsgründen kann js beim Entwurf nicht domänenübergreifend sein.

Was ist domänenübergreifend:

1. Wenn die Domainnamen unterschiedlich sind.

2. Die Domainnamen sind gleich, aber die Ports sind unterschiedlich.

Nur ​​wenn der Domainname und der Port gleich sind, können Sie darauf zugreifen.

Sie können JSONP verwenden, um domänenübergreifende Probleme zu lösen.

3. Domänenübergreifender Fehlerfall 3.1, Same-Origin-Richtlinie

Zuallererst verfügen Browser aus Sicherheitsgründen über einen Same-Origin-Richtlinienmechanismus. Die Same-Origin-Richtlinie verhindert das Laden von Eine Quelle oder ein Skript. Ruft Eigenschaften eines aus einer anderen Quelle geladenen Dokuments ab oder legt diese fest. Es scheint, dass ich nicht weiß, was es bedeutet, aber Sie werden es wissen, nachdem Sie es geübt haben.

3.2, erstellen Sie zwei Webseiten nach Belieben

Ein Port ist 2698 und der andere ist 2701. Per Definition stammen sie aus unterschiedlichen Quellen.

3.3, verwenden Sie jQuery, um Anfragen aus verschiedenen Quellen zu initiieren

Fügen Sie eine Schaltfläche auf der Webseite von Port 2698 hinzu, und das Click-Ereignis initiiert zwei zufällige Anfragen an den Port 2701 Domain-Anfrage.

$("#getOtherDomainThings").click(function () {
$.get("http://localhost:2701/Scripts/jquery-1.4.4.min.js", function (data) {
console.log(data)
})

$.get("http://localhost:2701/home/index", function (data) {
console.log(data)
})
})

Nach der Same-Origin-Strategie wird es offensichtlich tragisch sein. Der Browser blockiert die Anfrage und initiiert sie überhaupt nicht. (nicht erlaubt durch Access-Control-Allow-Origin)

OK, es stellt sich heraus, dass JSONP dieses Problem lösen soll.

Mit anderen Worten, die JSON-Daten eines anderen Projekts werden direkt in einem src oder einer URL angefordert.

Zum Beispiel wird in der URL der Seite im Projekt mit Port 8080 direkt die Anweisung http://localhost:8081/category.json angefordert, und diese Kategorie.json befindet sich im Verzeichnis der 8081 webapp Als nächstes wird eine domänenübergreifende Anforderungsaufforderung generiert.

Viertens. Domainübergreifende Lösung 4.1, Inspiration

Manchmal sehen wir solchen Code in Projekten

<script type="text/javascript" src="https://com/seashell/weixin/js/jquery.js"></script>

Auf diese Weise, auch wenn sie sich nicht im selben Projekt befinden, Die Anfrage kann auch erfolgreich sein. Diese Lücke oder Technologie wird genutzt, um großzügige Anfragen zu erreichen.

4.2, Methode (Fall 1) 4.2.1, Verwenden Sie ein Skript, um JSON aus verschiedenen Quellen zu erhalten

Da es JSONP heißt, ist es offensichtlich, dass der Zweck immer noch JSON ist. und es wird domänenübergreifend erhalten. Basierend auf der obigen Analyse ist es leicht vorstellbar: Verwenden Sie js, um ein Skript-Tag zu erstellen, weisen Sie die JSON-URL dem scr-Attribut des Skripts zu, fügen Sie das Skript in den Dom ein und lassen Sie es vom Browser abrufen. Übung:

function CreateScript(src) {
 $("<script><//script>").attr("src", src).appendTo("body")
}

Fügen Sie ein Schaltflächenereignis hinzu, um es zu testen:

$("#getOtherDomainJson").click(function () {
 $.get('http://localhost:2701/home/somejson', function (data) {
  console.log(data)
 })
})

Zuerst der erste Browser, http://localhost Die URL :2701/home/somejson verfügt zwar über einen JSON, und die Verwendung des Skript-Tags auf der 2698-Webseite zum Anfordern der URL 2701 ist ebenfalls 200OK, aber unten wird ein js-Syntaxfehler gemeldet. Es stellt sich heraus, dass die Antwort nach dem Laden mit dem Skript-Tag sofort als js ausgeführt wird. Offensichtlich ist {"Email": "zhww@outlook.com", "Remark": "Ich komme aus dem Fernen Osten"} rechtliche js-Anweisung.

4.2.2, verwenden Sie ein Skript, um fremdes JSONP zu erhalten

Natürlich ist es am einfachsten, das obige JSON in eine Rückrufmethode einzufügen. Es sieht zum Beispiel so aus:

Wenn die jsonpcallback-Methode vorhanden ist, dann jsonpcallback({"Email":"zhww@outlook.com","Remark":" „Ich komme aus Fernost“}) ist eine juristische js-Aussage.

Hier ist zu beachten, dass die ursprünglichen Daten im JSON-Format {"Email": "zhww@outlook.com", "Remark": "Ich komme aus dem Fernen Osten"} in jsonpcallback gekapselt werden müssen ({ „Email“: „zhww@outlook.com“, „Remark“: „Ich komme aus Fernost“}) Ein solches Skript kann während des Rückrufs geparst werden, andernfalls schlägt das Parsen fehl.

Da der Server den Rückruf des Clients nicht kennt, ist es unmöglich, ihn fest in jsonpcallback zu codieren. Daher wird ein QueryString mitgebracht, damit der Client dem Server mitteilen kann, was die Rückrufmethode ist Der Schlüssel von QueryString muss der Vereinbarung des Servers entsprechen, der oben genannte ist „Callback“.

Rückruffunktion hinzufügen:

function jsonpcallback(json) {
 console.log(json)
}

Ändern Sie leicht die Parameter der vorherigen Methode:

$("#getJsonpByHand").click(function () {
 CreateScript("http://localhost:2701/home/somejsonp?callback=jsonpcallback")
})

200OK, der Server Gibt jsonpcallback zurück({"Email": "zhww@outlook.com", "Remark": "Ich komme aus Fernost"}), wir haben auch die jsonpcallback-Methode geschrieben, die natürlich ausgeführt wird. OK, ich habe JSON erfolgreich erhalten. Das ist richtig, hier dreht sich alles um JSONP.

4.2.3, verwenden Sie jQuery, um JSONP zu erhalten

上面的方式中,又要插入script标签,又要定义一个回调,略显麻烦,利用jQuery可以直接得到想要的json数据,同样是上面的jsonp:

$("#getJsonpByJquery").click(function () {
$.ajax({
url: 'http://localhost:2701/home/somejsonp',
dataType: "jsonp",
jsonp: "callback",
success: function (data) {
console.log(data)
}
})
})

得到的结果跟上面类似。

4.2.4,总结

一句话就是利用script标签绕过同源策略,获得一个类似这样的数据,jsonpcallback是页面存在的回调方法,参数就是想得到的json。

jsonpcallback({"Email":"zhww@outlook.com","Remark":"我来自遥远的东方"})

4.3,案例二 4.3.1,简单应用

程序A中sample的部分代码:

<script type="text/javascript">
//回调函数
function callback(data) {
alert(data.message);
}
</script>
<script type="text/javascript" src="http://localhost:20002/test.js"></script>

程序B中test.js的代码:
1 //调用callback函数,并以json数据形式作为阐述传递,完成回调
2 callback({message:"success"});
这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

将JSON数据填充进回调函数,这就是JSONP的JSON+Padding的含义吧。

一般情况下,我们希望这个script标签能够动态的调用,而不是像上面因为固定在html里面所以没等页面显示就执行了,很不灵活。我们可以通过javascript动态的创建script标签,这样我们就可以灵活调用远程服务了。

4.3.2,简单应用的升级以一

程序A中sample的部分代码:

<script type="text/javascript">
function callback(data) {
alert(data.message);
}
//添加<script>标签的方法
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function(){
addScriptTag("http://localhost:20002/test.js");
}
</script>

程序B的test.js代码不变,我们再执行下程序,是不是和原来的一样呢。如果我们再想调用一个远程服务的话,只要添加addScriptTag方法,传入远程服务的src值就可以了。这里说明下为什么要将addScriptTag方法放入到window.onload的方法里,原因是addScriptTag方法中有句document.body.appendChild(script);,这个script标签是被添加到body里的,由于我们写的javascript代码是在head标签中,document.body还没有初始化完毕呢,所以我们要通过window.onload方法先初始化页面,这样才不会出错。

这样这个http://localhost:20002/test.js路径就可以动态的变化了。

4.3.3,简单应用的升级二

上面的例子是最简单的JSONP的实现模型,不过它还算不上一个真正的JSONP服务。我们来看一下真正的JSONP服务是怎么样的,比如Google的ajax搜索接口:http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=?&callback=?

q=?这个问号是表示你要搜索的内容,最重要的是第二个callback=?这个是正如其名表示回调函数的名称,也就是将你自己在客户端定义的回调函数的函数名传送给服务端,服务端则会返回以你定义的回调函数名的方法,将获取的json数据传入这个方法完成回调。有点罗嗦了,还是看看实现代码吧:

<script type="text/javascript">//添加<script>标签的方法function addScriptTag(src){ var script = document.createElement('script');script.setAttribute("type","text/javascript");script.src = src;document.body.appendChild(script);}window.onload = function(){//搜索apple,将自定义的回调函数名result传入callback参数中addScriptTag("http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=apple&callback=result");}//自定义的回调函数resultfunction result(data) {//我们就简单的获取apple搜索结果的第一条记录中url数据alert(data.responseData.results[0].unescapedUrl);}</script>

这个result方法是自己定义的,可能服务器上有千千万万个类似于result 的回调函数,但是我现在要的就是result而不是其它的方法,所以在这里自己定义回调方法。而不是写死的。可能下一次我就改成result1,result2,result3,等了只要自己把回调方法的名称改一下就行了。

4.4.4,jquery对jsonp的支持

jQuery框架也当然支持JSONP,可以使用$.getJSON(url,[data],[callback])方法(详细可以参考http://api.jquery.com/jQuery.getJSON/)。那我们就来修改下程序A的代码,改用jQuery的getJSON方法来实现(下面的例子没用用到向服务传参,所以只写了getJSON(url,[callback])):

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
 $.getJSON("http://localhost:20002/MyService.ashx?callback=?",function(data){
  alert(data.name + " is a a" + data.sex);
 });
</script>

结果是一样的,要注意的是在url的后面必须添加一个callback参数,这样getJSON方法才会知道是用JSONP方式去访问服务,callback后面的那个问号是内部自动生成的一个回调函数名。这个函数名大家可以debug一下看看,比如jQuery17207481773362960666_1332575486681。

当然,加入说我们想指定自己的回调函数名,或者说服务上规定了固定回调函数名该怎么办呢?我们可以使用$.ajax方法来实现(参数较多,详细可以参考http://api.jquery.com/jQuery.ajax)。先来看看如何实现吧:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
 $.ajax({
  url:"http://localhost:20002/MyService.ashx?callback=?", 
  dataType:"jsonp",
  jsonpCallback:"person",
  success:function(data){
   alert(data.name + " is a a" + data.sex);
  }
 });
</script>

没错,jsonpCallback就是可以指定我们自己的回调方法名person,远程服务接受callback参数的值就不再是自动生成的回调名,而是person。dataType是指定按照JSOPN方式访问远程服务。

相关推荐:

Jsonp的原理以及简单实现的方法

jsonp的原理,封装jsonp的方法介绍

js/ajax跨越访问-jsonp的原理和实例(javascript和jquery实现代码)_javascript技巧

Das obige ist der detaillierte Inhalt vonBeherrschen Sie die Prinzipien und die Implementierung von JSONP vollständig. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn