> 웹 프론트엔드 > JS 튜토리얼 > JSONP는 Ajax 도메인 간 문제를 해결합니다(코드 포함).

JSONP는 Ajax 도메인 간 문제를 해결합니다(코드 포함).

php中世界最好的语言
풀어 주다: 2018-04-26 14:49:11
원래의
1742명이 탐색했습니다.

이번에는 Ajax 크로스 도메인 문제를 해결하기 위해 JSONP를 소개합니다(코드 포함). JSONP가 Ajax 크로스 도메인 문제를 해결하는 데 사용할 수 있는 주의 사항은 무엇입니까?

JSON과 JSONP

 JSONP와 JSON이 비슷해 보이죠?

  JSON(JavaScript Object Notation)은 경량 데이터 교환 형식입니다. 누구나 JSON에 대해 잘 알고 있어야 합니다. JSON에 대해 잘 모르는 친구는 json.org를 방문하여 간단하고 쉽게 알아볼 수 있습니다.

 JSONP는 JSON의 약어로 Padding을 추가한 것입니다. 이는 서버 측에서 스크립트 태그를 통합하고 이를 클라이언트에 반환하여 자바스크립트 콜백 형식으로 도메인 간 액세스를 가능하게 하는 비공식 프로토콜입니다(이는 JSONP의 간단한 구현일 뿐입니다).

 JSONP는 JSON+Padding(여기서 Padding은 패딩으로 이해함)과 같습니다. 먼저 아래의 작은 예를 살펴보고 자세히 소개하겠습니다.

동일출처 정책

왜 이런 오류가 발생하나요? 이는 Javascript를 지원하는 모든 브라우저가 동일 출처 정책을 사용하기 때문입니다. Baidu의 설명을 살펴보세요:

Netscape가 제안한 유명한 보안 정책인 동일 출처 정책. JavaScript를 지원하는 모든 브라우저는 이제 이 전략을 사용합니다. 소위 동일한 출처는 도메인 이름, 프로토콜 및 포트가 동일함을 의미합니다. Baidu와 Google 페이지가 브라우저의 두 탭 페이지에서 열리면 Baidu 브라우저가 스크립트를 실행할 때 스크립트가 어느 페이지에 속하는지, 즉 스크립트가 Baidu와 동일한 출처인지 확인하게 됩니다. 실행.

 이것이 데이터를 얻을 수 없는 이유입니다. 그렇다면 크로스 도메인 문제를 어떻게 해결할 수 있을까요? 맞습니다. 이제 본론으로 들어가서 JSONP가 무엇인지 이해할 수 있습니다.

크로스 도메인의 간단한 원리

정의만 봐서는 그다지 명확하지 않으니, 먼저 수동으로 간단하고 이해하기 쉬운 테스트를 해보겠습니다. 새로운 asp.net 웹 프로그램을 만들고, 샘플.html 웹 페이지와 test.js 파일을 추가하세요. 코드는 다음과 같습니다:

sample.html 코드:

 <!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 코드:

alert("success");
로그인 후 복사

샘플.html을 열면 "성공"과 같은 메시지 상자가 나타납니다. 이는 아무 의미가 없는 것 같습니다. 크로스 도메인 문제를 해결하는 방법은 무엇입니까? 자, 이제 비동질적인 환경을 시뮬레이션합니다. Visual Studio를 사용하여 새 웹 프로그램(여기서는 프로그램 A라고 함)을 만듭니다. 이제 새 Visual Studio를 열고 새 웹 프로그램(프로그램 B)을 만듭니다. ). ), 프로그램 A에서 이전 test.js 파일을 제거하고 프로그램 B에 복사합니다. 두 프로그램이 모두 실행된 후 Visual Studio에서는 프로그램 A가 localhost:20001이고 프로그램 B가 localhost:20002라고 가정합니다. 이는 도메인 이름은 동일하지만 포트는 동일합니다. 숫자가 다르기 때문에 균일하지 않습니다.)

 좋아요, test.js 파일이 프로그램 B에 있고 URL이 localhost:20002가 되므로 다음으로 Sample.html의 코드를 변경해야 합니다.

sample.html 코드 부분:

<script type="text/javascript" src="http://localhost:20002/test.js"></script>
로그인 후 복사

두 개의 웹 프로그램 AB를 계속 실행하세요. localhost:20001/sample.html을 다시 새로 고치면 이전과 같이 "성공" 대화 상자가 나타납니다. 동일한 출처가 아닌 소위 원격 서비스인 localhost:20002/test.js에 성공적으로 액세스했습니다. 이 시점에서는 모든 사람이 도메인 간 액세스의 원칙을 대략적으로 이해해야 한다고 생각합니다.

 <script> 태그의 src 속성은 동일 출처 정책에 의해 제한되지 않으므로 서버에서 어떤 스크립트라도 얻어서 실행할 수 있습니다. </p> <p style="text-align: left;"><span style="background-color: #808080">JSONP 구현 모드--CallBack</span></p> <p style="text-align: left;"> 작은 예에서는 교차 도메인의 원리를 설명했을 뿐입니다. 다시 JSONP 정의에 언급된 자바스크립트 콜백의 형식을 살펴보겠습니다. 그럼 코드를 수정하고 JSONP의 자바스크립트 콜백 형태를 구현하는 방법을 살펴보겠습니다. </p> <p style="text-align: left;">프로그램 A의 샘플 코드 일부: </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><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>

로그인 후 복사

프로그램 B의 test.js 코드:

//콜백 함수를 호출하고 설명으로 json 데이터 형식으로 전달하여 콜백을 완료합니다

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数据实现方法

위 내용은 JSONP는 Ajax 도메인 간 문제를 해결합니다(코드 포함).의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 추천
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿