jsonp 프로토콜의 심층 분석principle_json
현재 공동 디버깅을 개발하는 과정에서 jquery를 사용하므로 당연히 dataType:'jsonp'를 사용하면 문제를 쉽게 해결할 수 있습니다.
그런데 당시 백엔드가 jsonp 액세스를 지원하지 않았기 때문에 나중에 이 기능을 구현할 때 jsonp 형식으로 반환되는 형식이 무엇인지 물었습니다. 사용법만 알았을 뿐, 답은 알 수 없었습니다. . .
나중에 해결됐지만 문제해결을 좋아하는 저는 항상 고민을 많이 하게 되어서 정보를 읽기 시작했고, 보고 나서 갑자기 깨달음을 느꼈습니다. 할 계획입니다. 모든 사람과 공유할 메모입니다.
JSON과 JSONP의 차이점
JSON과 JSONP 사이에는 문자가 하나만 다르지만 실제로는 전혀 동일하지 않습니다. JSON은 데이터 교환 형식이고 JSONP는 JSONP 방법을 사용하여 얻을 수 있는 것입니다. 여전히 json 형식의 데이터입니다.
직접 말하면 用JSON来传数据,靠JSONP来跨域
.
JSONP 자세히 설명
우리 모두는 一个页面的ajax只能获取和此页面同域的数据。
알고 있습니다. 따라서 도메인 전체에서 데이터를 가져와야 할 경우 JSONP 방법을 사용하여 가져와야 합니다.
아래 그림과 같이 크로스 도메인 데이터를 얻기 위해 json 형식을 사용하여 반환되는 오류 메시지입니다.
그럼 어떻게 해결하나요? 프레임워크를 사용하는 프론트엔드 아동용 신발에는 나름의 대응 메소드가 있을 수 있습니다. 예를 들어 jquery는 dataType设为jsonp
만 추가하면 해결할 수 있는데, 우리가 사용해보면 왜 이런 식으로 해결될 수 있는지 생각해 본 적이 있나요? 중심 아이디어는 무엇입니까?
다음은 자세한 설명입니다. 첫 번째 아이디어는 scirpt 태그를 사용하여 교차 도메인 데이터를 도입하는 것입니다. jsonp의 과정을 처음부터 천천히 살펴보겠습니다.
가이드 1단계
쓰기b.com/b.js
내용:
그런 다음 a.com/a.html
내용을 작성하세요.
a.html을 실행하면 결과가 뻔하고 hello가 확실히 팝업됩니다.
가이드 2단계
b.com/b.js
파일 콘텐츠 수정:
그런 다음 a.com/a.html
콘텐츠를 수정합니다.
<script type='text/javascript' src='http://b.com/b.js'> <script> function myFunction(str) { //定义处理数据的函数 alert(str + ' world'); } </script>
a.html을 실행하면 'hello world' 팝업이 나타납니다. 이것에 대해서는 의심의 여지가 없습니다.
가이드 3단계
위의 2단계를 다시 살펴보겠습니다. b.js의 'hello'는 b.com 도메인 이름 아래의 데이터이며, a.com/a.html에서 실행되어 표시될 수 있습니다. 이것은 이미 跨域请求数据了
구현되었나요?
또한 스크립트 태그의 src가 반드시 js 파일을 가리키는 것은 아니기 때문에 어떤 주소든 가리킬 수 있습니다.
따라서 위의 2단계에서 a.html의 내용을 <script type='text/javascript' src='http://b.com/b.js'>
로 변경하고, b.js
을 b.html
또는 b.json
등으로 변경할 수 있으며 실행이 정상적으로 반환됩니다.
안내 4단계
위 데이터는 모두 정적이며 파일에 하드 코딩되어 있어 우리의 요구 사항을 충족할 수 없습니다. . . Ajax 요청 데이터는 실시간으로 변경되므로 데이터를 동적으로 만들어야 합니다.
스크립트 테이블에서 동적 페이지(인터페이스)를 호출하여 동적 데이터를 얻을 수 있습니다. 여기서는 回调函数
을 생각해 보겠습니다.
편집 a.com/a.html
페이지 콘텐츠:
<script type='text/javascript' src='http://b.com/b.aspx?callback=myFunction'> <script> function myFunction(str){ //定义处理数据的函数 alert(str + ' world'); } </script>
src 참조 주소에 ?callback=myFunction
을 추가했는데, 이는 데이터를 표시하는 함수도 동적으로 전달된다는 의미입니다.
jsonp 메소드를 사용하여 데이터를 얻는 또 다른 중요한 점은 后端接口也要支持jsonp才行
입니다. 예를 들어 다음 코드는 반환된 데이터를 jsonp 형식으로 변경합니다. 계속 읽어보세요. (여기서는 .net 언어가 예로 사용되었습니다. )
protected void page_load(object sender, EventArgs e){ if(this.IsPostBack == false){ string callback = ''; if(Request["callback"] != null){ callback = request["callback"]; string data = "hello"; Response.Write(callback+"("+ data + ")"); //接口页面返回的数据格式“函数(参数)”的格式。 } } }
代码的意思很简单,就是获取调用函数的参数。如果这里调用b.aspx?callback=myFunction
的话,则会返回myFunction('hello')
,如果后端代码给data赋值一个变量,这里的‘hello'则变成了动态的数据了。
引导步骤5
再看上面的步骤,虽然获取的数据是动态的了,但在页面上引入一个script标签,却只能执行一次,获取一次,显然还是不能满足需求的。所以我们在需要的时候,就得动态的添加一次这样的script标签。
所以我们在这里需要封装一个函数:
function addScript(src){ var script = document.createElement('script'); script.setAttribute('type','text/javascript'); script.src= src; document.body.appendChild(script); }
需要调用的时候,就去执行:
addScript('b.com/b.aspx?callback=myFunction'); function myFunction(data){//定义处理数据的函数 alert(data); }
ok,上面的过程就是jsonp的原理,我们不必去记住那些令人纠结不清的定义,只要看一遍这个过程,我相信就能明白其中的精髓了吧。
jquery实现跨域
jquery跨域方法
$.ajax({ url: 'b.com/b.json', //不同的域 type: 'GET', // jsonp模式只有GET是合法的 dataType: 'jsonp', // 数据类型 jsonp: 'callback', // 指定回调函数名,与服务器端接收的一致,并回传回来 success: function(data) { console.log(data); } })
使用jquery非常方便,那么它是怎么实现这个转化的呢?下面我们来看看这部分的jquery源码。
jq实现jsonp源码分析
我贴出网上给的jquery实现jsonp部分的源码分析:
if (s.dataType == "jsonp") { // 构建jsonp请求字符集串。jsonp是跨域请求,要加上callback=?后面将会加函数名 if (type == "GET") { //使get的url包含 callback=?后面将 会进行加函数名 if (!s.url.match(jsre)) s.url += (s.url.match(/?/) ? "&" : "?") + (s.jsonp || "callback") + "=?"; } // 构建新的s.data,使其包含 callback=function name else if (!s.data || !s.data.match(jsre)) s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?"; s.dataType = "json"; } //判断是否为jsonp,如果是 ,进行处理。 if (s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre))) { jsonp = "jsonp" + jsc ++; //为请 求字符集串的callback=加上生成回调函数名 if (s.data) s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1"); s.url = s.url.replace(jsre, "=" + jsonp + "$1"); // 我们需要保证jsonp 类 型响应能正确地执行 //jsonp的类型必须为script。这样才能执行服 务器返回的 //代码。这里就是调用这个回调函数。 s.dataType = "script"; //window下注册一个jsonp回调函数 有,让ajax请求返回的代码调用执行它, window[jsonp] = function(tmp) { data = tmp; success(); complete(); // 垃圾回收,释放联变量,删除jsonp的对象,除去head中加的script元素 window[jsonp] = undefined; try { delete window[jsonp]; } catch (e) {} if (head) head.removeChild(script); }; } if (s.data && type == "GET") { // data有效,追加到get类型的url上去 s.url += (s.url.match(/?/) ? "&" : "?") + s.data; // 防止IE会重复发送get和post data s.data = null; } if (s.dataType == "script" && type == "GET" && parts && (parts[1] && parts[1] != location.protocol || parts[2] != location.host)) { // 在head中加上<script src=""></script> var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); script.src = s.url; if (s.scriptCharset) script.charset = s.scriptCharset; if (!jsonp) { //如果datatype不是jsonp,但是url却是跨域 的。采用scriptr的onload或onreadystatechange事件来触发回 调函数。 var done = false; // 对所有浏览器都加上处理器 script.onload = script.onreadystatechange = function() { if (!done && (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")) { done = true; success(); complete(); head.removeChild(script); } }; } head.appendChild(script); // 已经使用 了script 元素注射来处理所有的事情 return undefined; }
上面的代码稍显复杂,但是我们挑拣重要的看就好了。
我们来分析一下这个过程,其实这个过程也就是上面我提出问题的答案
了:
这里执行代码之后,其实就是判断是否配置了dataType: 'jsonp',如果是jsonp协议,则要在url上加callback=jQueryxxx(函数名),jquery会把url转化为:http://b.com/b.json?callback=jQueryxxx
,然后再在html中插入,加载完b.json这个文件后,就会执行jQueryxxx这个回调函数,而且此时这个函数里面已经存在了动态数据(json格式数据),所以在页面上执行的时候就能够随心所欲的处理数据了,但是也别忘了后端也要支持jsonp格式才行。所以这样就达到了跨域获取数据的功能。
原生js封装jsonp
function jsonp(config) { var options = config || {}; // 需要配置url, success, time, fail四个属性 var callbackName = ('jsonp_' + Math.random()).replace(".", ""); var oHead = document.getElementsByTagName('head')[0]; var oScript = document.createElement('script'); oHead.appendChild(oScript); window[callbackName] = function(json) { //创建jsonp回调函数 oHead.removeChild(oScript); clearTimeout(oScript.timer); window[callbackName] = null; options.success && options.success(json); //先删除script标签,实际上执行的是success函数 }; oScript.src = options.url + '?' + callbackName; //发送请求 if (options.time) { //设置超时处理 oScript.timer = setTimeout(function () { window[callbackName] = null; oHead.removeChild(oScript); options.fail && options.fail({ message: "超时" }); }, options.time); } };
这是我自己写的一个原生js实现jsonp获取跨域数据的方法。
我们只需要调用jsonp函数就能够跨域获取数据了。比如:
jsonp({ url: '/b.com/b.json', success: function(d){ //数据处理 }, time: 5000, fail: function(){ //错误处理 } })
再说几点注意的地方:
使用jsonp方法时,在控制台的network-JS
中才能找到调用的接口,不再是XHR类了。由于页面渲染的时候script只执行一次,而且动态数据需要多次调用,所以在插入使用之后需要删除,并且要初始化回调函数。原生js实现时,最好加一个请求超时的功能,方便调试。
总之jsonp就是一种获取跨域json数据的方法。

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











JavaScript 문자열 교체 방법 및 FAQ에 대한 자세한 설명 이 기사는 JavaScript에서 문자열 문자를 대체하는 두 가지 방법 인 내부 JavaScript 코드와 웹 페이지의 내부 HTML을 탐색합니다. JavaScript 코드 내부의 문자열을 교체하십시오 가장 직접적인 방법은 대체 () 메소드를 사용하는 것입니다. str = str.replace ( "find", "replace"); 이 메소드는 첫 번째 일치 만 대체합니다. 모든 경기를 교체하려면 정규 표현식을 사용하고 전역 플래그 g를 추가하십시오. str = str.replace (/fi

손쉬운 웹 페이지 레이아웃에 대한 jQuery 활용 : 8 에센셜 플러그인 jQuery는 웹 페이지 레이아웃을 크게 단순화합니다. 이 기사는 프로세스를 간소화하는 8 개의 강력한 JQuery 플러그인을 강조합니다. 특히 수동 웹 사이트 생성에 유용합니다.

그래서 여기 당신은 Ajax라는이 일에 대해 배울 준비가되어 있습니다. 그러나 정확히 무엇입니까? Ajax라는 용어는 역동적이고 대화식 웹 컨텐츠를 만드는 데 사용되는 느슨한 기술 그룹을 나타냅니다. 원래 Jesse J에 의해 만들어진 Ajax라는 용어

10 재미있는 jQuery 게임 플러그인 웹 사이트를보다 매력적으로 만들고 사용자 끈적함을 향상시킵니다! Flash는 여전히 캐주얼 웹 게임을 개발하기위한 최고의 소프트웨어이지만 JQuery는 놀라운 효과를 만들 수 있으며 Pure Action Flash 게임과 비교할 수는 없지만 경우에 따라 브라우저에서 예기치 않은 재미를 가질 수 있습니다. jQuery tic 발가락 게임 게임 프로그래밍의 "Hello World"에는 이제 jQuery 버전이 있습니다. 소스 코드 jQuery Crazy Word Composition 게임 이것은 반은 반은 게임이며, 단어의 맥락을 알지 못해 이상한 결과를 얻을 수 있습니다. 소스 코드 jQuery 광산 청소 게임

기사는 JavaScript 라이브러리 작성, 게시 및 유지 관리, 계획, 개발, 테스트, 문서 및 홍보 전략에 중점을 둡니다.

이 튜토리얼은 jQuery를 사용하여 매혹적인 시차 배경 효과를 만드는 방법을 보여줍니다. 우리는 멋진 시각적 깊이를 만드는 계층화 된 이미지가있는 헤더 배너를 만들 것입니다. 업데이트 된 플러그인은 jQuery 1.6.4 이상에서 작동합니다. 다운로드

이 JavaScript 라이브러리는 Window.Name 속성을 활용하여 쿠키에 의존하지 않고 세션 데이터를 관리합니다. 브라우저에 세션 변수를 저장하고 검색하기위한 강력한 솔루션을 제공합니다. 라이브러리는 세 가지 핵심 방법을 제공합니다 : 세션

이 튜토리얼은 Ajax를 통해로드 된 동적 페이지 상자를 작성하여 전체 페이지 재 장전없이 인스턴트 새로 고침을 가능하게합니다. jQuery 및 JavaScript를 활용합니다. 맞춤형 Facebook 스타일 컨텐츠 박스 로더로 생각하십시오. 주요 개념 : Ajax와 JQuery
