Heim  >  Artikel  >  Web-Frontend  >  JSONP löst das domänenübergreifende Ajax-Problem (mit Code)

JSONP löst das domänenübergreifende Ajax-Problem (mit Code)

php中世界最好的语言
php中世界最好的语言Original
2018-04-26 14:49:111708Durchsuche

Dieses Mal werde ich Ihnen JSONP vorstellen, um domänenübergreifende Ajax-Probleme zu lösen (mit Code). sehen.

JSON und JSONP

Gibt es einen Zusammenhang zwischen JSONP und JSON?

JSON (

JavaScript

Object Notation) ist ein leichtes Datenaustauschformat. Jeder sollte mit JSON vertraut sein. Freunde, die damit nicht sehr vertraut sind, können sich auf json.org informieren. Es ist einfach und leicht zu verstehen. JSONP ist die Abkürzung für JSON mit

Padding

. Es handelt sich um ein inoffizielles Protokoll, das die Integration von Skript-Tags auf der Serverseite und deren Rückgabe an den Client ermöglicht und so einen domänenübergreifenden Zugriff in Form von Javascript-Rückrufen ermöglicht (dies ist nur eine einfache Implementierung von JSONP). JSONP ist genau wie JSON+Padding (wir verstehen unter „Padding“ zunächst das kleine Beispiel unten und stellen es dann im Detail vor).

Same Origin Policy

Warum tritt ein solcher Fehler auf? Dies liegt daran, dass alle Browser, die Javascript unterstützen, die Same-Origin-Richtlinie verwenden. Schauen Sie sich Baidus Erklärung an:

Same-Origin-Policy, eine berühmte Sicherheitsrichtlinie, die von Netscape vorgeschlagen wurde. Alle Browser, die JavaScript unterstützen, verwenden mittlerweile diese Strategie. Der sogenannte Same Origin bedeutet, dass Domainname, Protokoll und Port gleich sind. Wenn Baidu- und Google-Seiten auf zwei Registerkarten eines Browsers geöffnet werden und ein Baidu-Browser ein Skript ausführt, prüft er, zu welcher Seite das Skript gehört, dh ob es denselben Ursprung hat wie das Skript hingerichtet.

Aus diesem Grund können die Daten nicht abgerufen werden. Wie können wir also das domänenübergreifende Problem lösen? Das ist richtig, jetzt können wir auf den Punkt kommen und verstehen, was JSONP ist.

Das einfache Prinzip von Cross-Domain

Es ist nicht ganz klar, wenn man sich nur die Definition ansieht, also führen wir zunächst einen einfachen und leicht verständlichen Test manuell durch . Erstellen Sie ein neues Webprogramm von

asp.net

, fügen Sie die Webseite „sample.html“ und eine test.js-Datei hinzu. Der Code lautet wie folgt:

Sample.html-Code:

 <!DOCTYPE html PUBLIC "-//WC//DTD XHTML . Transitional//EN" "http://www.w.org/TR/xhtml/DTD/xhtml-transitional.dtd">
 <html xmlns="http://www.w.org//xhtml" >
 <head>
   <title>test</title>
   <script type="text/javascript" src="test.js"></script>
 </head>
 <body>
 </body>
 </html>

test.js-Code:

alert("success");
Nach dem Öffnen von „sample.html“ wird ein Meldungsfeld wie „Erfolg“ angezeigt. Dies scheint nicht der Fall zu sein Domänenübergreifend Wie kann das Problem gelöst werden? Okay, jetzt simulieren wir eine inhomogene Umgebung. Haben wir nicht einfach Visual Studio verwendet, um ein neues Webprogramm zu erstellen (hier nennen wir es Programm A?). Jetzt öffnen wir ein neues Visual Studio und erstellen ein neues Webprogramm (Programm B). ). ), entfernen Sie unsere vorherige test.js-Datei aus Programm A und kopieren Sie sie in Programm B. Nachdem beide Programme ausgeführt wurden, startet Visual Studio den integrierten Server. Angenommen, Programm A ist localhost:20001 und Programm B ist localhost:20002. Dies simuliert eine inhomogene Umgebung (obwohl der Domänenname derselbe ist, aber der Port). Zahl ist unterschiedlich, also inhomogen).

OK, als nächstes sollten wir den Code in sample.html ändern, da sich die Datei test.js in Programm B befindet und die URL zu localhost:20002 wird.

Sample.html Teil des Codes:

<script type="text/javascript" src="http://localhost:20002/test.js"></script>
Bitte lassen Sie die beiden Webprogramme AB laufen, wenn Sie localhost:20001/sample.html erneut aktualisieren. Das Dialogfeld „Erfolg“ wird wie zuvor angezeigt. Ja, auf den sogenannten Remote-Dienst von localhost:20002/test.js, der nicht vom gleichen Ursprung ist, wurde erfolgreich zugegriffen. An dieser Stelle glaube ich, dass jeder ein grobes Verständnis der Prinzipien des domänenübergreifenden Zugriffs haben sollte.

Das src-Attribut des <script>-Tags ist nicht durch die Same-Origin-Richtlinie eingeschränkt, sodass Sie jedes Skript auf dem Server abrufen und ausführen können. </p> <p style="text-align: left;"></p>JSONP-Implementierungsmodus - CallBack<p style="text-align: left;"><span style="background-color: #808080"></span> Das kleine Beispiel hat gerade das Prinzip der domänenübergreifenden Funktionsweise erläutert. Gehen wir zurück und werfen wir einen Blick auf die Definition von JSONP Informationen zum Javascript-Rückrufformular. Dann ändern wir den Code und die Implementierung der Javascript-Rückrufform von JSONP. </p> <p style="text-align: left;">Teil des Beispielcodes in Programm A: </p> <pre class="brush:php;toolbar:false"> <script type="text/javascript">  //回调函数  function callback(data) {     alert(data.message);   }   </script>   <script type="text/javascript" src="http://localhost:20002/test.js"></script>

Der Code von test.js in Programm B:

//Rufen Sie die Rückruffunktion auf und übergeben Sie sie als Erklärung in Form von JSON-Daten, Abschlussrückruf

callback({message:"success"});

  这其实就是JSONP的简单实现模式,或者说是JSONP的原型:创建一个回调函数,然后在远程服务上调用这个函数并且将JSON 数据形式作为参数传递,完成回调。

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

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

程序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:/test.js"); 
   } 
 </script>

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

  上面的例子是最简单的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=.&q=apple&callback=result");
   }
   //自定义的回调函数result
   function result(data) {
     //我们就简单的获取apple搜索结果的第一条记录中url数据
     alert(data.responseData.results[].unescapedUrl);
   }
 </script>

像这样的JSONP服务还有很多(以下信息来自使用 JSONP 实现跨域通信,第 1 部分: 结合 JSONP 和 jQuery 快速构建强大的 mashup):

接下来我们自己来创建一个简单的远程服务,实现和上面一样的JSONP服务。还是利用Web程序A和程序B来做演示,这次我们在程序B上创建一个MyService.ashx文件。

程序B的MyService.ashx代码:

 public class MyService : IHttpHandler 
   { 
     public void ProcessRequest(HttpContext context) 
     { 
       //获取回调函数名 
       string callback = context.Request.QueryString["callback"]; 
       //json数据 
       string json = "{\"name\":\"chopper\",\"sex\":\"man\"}"; 
 
       context.Response.ContentType = "application/json"; 
       //输出:回调函数名(json数据)
       context.Response.Write(callback + "(" + json + ")");
     } 
 
     public bool IsReusable 
     { 
       get 
       { 
         return false; 
       } 
     } 
   }

程序A的sample代码中的调用:

 <script type="text/javascript">   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:/MyService.ashx?callback=person");
   }
   //回调函数person   function person(data) {
     alert(data.name + " is a " + data.sex);
   }
 </script>  

  这就完成了一个最基本的JSONP服务调用了,是不是很简单,下面我们来了解下JQuery是如何调用JSONP的。

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方式访问远程服务。

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

AJAX二级联动有哪些实现方法

php+jquery传递json数据实现方法

Das obige ist der detaillierte Inhalt vonJSONP löst das domänenübergreifende Ajax-Problem (mit Code). 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