크로스 도메인 문제를 고려하여 이 글에서는 주로 jsonp의 원리에 대한 자세한 분석, jsonp의 원리에 대한 자세한 분석 및 사진과 텍스트를 포함한 크로스 도메인 문제의 요약을 제공합니다. 그것이 당신을 도울 수 있기를 바랍니다.
jsonp
1의 원리 및 구현 방법에 대한 자세한 분석: 도메인 간 문제.
둘째, 크로스 도메인이 발생하는 이유
J는 크로스 도메인 요청을 할 수 없습니다. 보안상의 이유로 js는 설계 시 도메인 간일 수 없습니다.
크로스도메인이란?
1. 도메인 이름이 다른 경우.
2. 도메인 이름은 동일하지만 포트가 다릅니다.
도메인 이름과 포트가 동일해야 접속 가능합니다.
jsonp를 사용하여 도메인 간 문제를 해결할 수 있습니다.
세 가지, 도메인 간 실패 사례 3.1, 동일 출처 정책
우선, 보안상의 이유로 브라우저에는 동일 출처 정책 메커니즘이 있습니다. 동일 출처 정책은 한 소스에서 로드된 문서나 스크립트가 소스에서 로드한 문서의 다른 속성을 설정합니다. 나는 그것이 무슨 뜻인지 모르는 것 같지만, 연습하고 나면 알게 될 것입니다.
3.2, 두 개의 웹 페이지를 생성하세요
한 포트는 2698이고 다른 포트는 2701입니다. 정의에 따르면 두 포트는 서로 다른 소스에서 왔습니다.
3.3, jQuery를 사용하여 다양한 소스에서 요청 시작
웹 페이지에 포트 2698로 버튼을 추가하면 Click 이벤트가 포트 2701로 도메인에 두 개의 요청을 시작합니다.
$("#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) }) })
동일출산정책에 따르면 당연히 비극이겠죠. 브라우저는 요청을 차단하고 전혀 시작하지 않습니다. (Access-Control-Allow-Origin에서는 허용되지 않음)
알겠습니다. jsonp가 이 문제를 해결하는 것으로 나타났습니다.
즉, 다른 프로젝트의 json 데이터를 src나 url로 직접 요청한다는 뜻입니다.
예를 들어 포트 8080을 사용하는 프로젝트의 페이지 URL에서 http://localhost:8081/category.json 문을 직접 요청하고 이 Category.json이 8081의 webapp 디렉터리에 있는 경우, 도메인 간 요청에 대한 메시지가 표시됩니다.
네 가지, 크로스 도메인 솔루션 4.1, Inspiration
프로젝트에서 이런 코드를 종종 볼 수 있습니다
<script type="text/javascript" src="https://com/seashell/weixin/js/jquery.js"></script>
이렇게 하면 같은 프로젝트에 있지 않아도 요청이 성공할 수 있습니다. 이 허점 또는 기술은 관대 한 요청을 달성하는 데 사용됩니다.
4.2, 방법(사례 1) 4.2.1, 스크립트를 사용하여 다양한 소스에서 json 가져오기
jsonp라고 하므로 목적은 여전히 json이고 도메인 간에 가져오는 것이 분명합니다. 위의 분석을 바탕으로 생각하기 쉽습니다. js를 사용하여 스크립트 태그를 구성하고, json url을 스크립트의 scr 속성에 할당하고, 스크립트를 dom에 삽입하고, 브라우저가 이를 얻도록 합니다. 연습:
function CreateScript(src) { $("<script><//script>").attr("src", src).appendTo("body") }
테스트할 버튼 이벤트 추가:
$("#getOtherDomainJson").click(function () { $.get('http://localhost:2701/home/somejson', function (data) { console.log(data) }) })
우선, 첫 번째 브라우저인 URL http://localhost:2701/home/somejson에는 json이 있고 2698에 있습니다. 2701 Url을 요청하는 웹 페이지의 스크립트 태그도 200 OK이지만 하단에 js 구문 오류가 보고됩니다. 스크립트 태그를 로드한 후 응답은 즉시 js로 실행됩니다. 분명히 {"Email":"zhww@outlook.com","Remark":"I came from the Far east"}는 a가 아닙니다. 법적 js 진술.
4.2.2, 스크립트를 사용하여 외부 jsonp를 얻습니다
분명히 위의 json을 콜백 메소드에 넣는 것이 가장 간단한 방법입니다. 예를 들어 다음과 같습니다.
jsonpcallback 메서드가 존재하는 경우 jsonpcallback({"Email":"zhww@outlook.com","Remark":"I came from the Far east"})는 다음과 같습니다. 법적 js 진술.
여기서 주목해야 할 점은 원본 json 형식 데이터 {"Email":"zhww@outlook.com","Remark":"I came from the Far east"}가 jsonpcallback({"Email ": "zhww@outlook.com","Remark":"나는 극동에서 왔습니다."}) 이러한 스크립트는 콜백 중에 구문 분석될 수 있습니다. 그렇지 않으면 구문 분석이 실패합니다.
서버는 클라이언트의 콜백이 무엇인지 모르기 때문에 이를 jsonpcallback에 하드 코딩하는 것은 불가능하므로 클라이언트가 서버에 콜백 메서드가 무엇인지 알려줄 수 있도록 QueryString을 가져옵니다. 물론 QueryString의 키는 반드시 있어야 합니다. 위의 내용은 "콜백"입니다.
콜백 함수 추가:
function jsonpcallback(json) { console.log(json) }
이전 방법의 매개변수를 약간 변경합니다:
$("#getJsonpByHand").click(function () { CreateScript("http://localhost:2701/home/somejsonp?callback=jsonpcallback") })
200OK, 서버는 jsonpcallback({"Email":"zhww@outlook.com","Remark":"I를 반환합니다. 'm from Far East"}), 물론 실행될 jsonpcallback 메서드도 작성했습니다. 좋아, json을 성공적으로 얻었습니다. 맞습니다. 이것은 jsonp에 관한 것입니다.
4.2.3, jQuery를 사용하여 jsonp를 가져옵니다
上面的方式中,又要插入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方式访问远程服务。
相关推荐:
js/ajax跨越访问-jsonp的原理和实例(javascript和jquery实现代码)_javascript技巧
위 내용은 jsonp의 원리와 구현을 완전히 마스터하세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!