Ajax jsonp跨域請(qǐng)求實(shí)現(xiàn)方法
什么是跨域?
簡(jiǎn)單的來說,出于安全方面的考慮,頁面中的JavaScript無法訪問其他服務(wù)器上的數(shù)據(jù),即“同源策略”。而跨域就是通過某些手段來繞過同源策略限制,實(shí)現(xiàn)不同服務(wù)器之間通信的效果。
具體策略限制情況可看下表:
URL | 說明 | 允許通信 |
http://www.a.com/a.js http://www.a.com/b.js |
同一域名下 | 允許 |
http://www.a.com/lab/a.js http://www.a.com/script/b.js |
同一域名下不同文件夾 | 允許 |
http://www.a.com:8000/a.js http://www.a.com/b.js |
同一域名,不同端口 | 不允許 |
http://www.a.com/a.js https://www.a.com/b.js |
同一域名,不同協(xié)議 | 不允許 |
http://www.a.com/a.js http://127.0.0.100/b.js |
域名和域名對(duì)應(yīng)ip | 不允許 |
http://www.a.com/a.js http://script.a.com/b.js |
主域相同,子域不同 | 不允許 |
http://www.a.com/a.js http://a.com/b.js |
同一域名,不同二級(jí)域名(同上) | 不允許 |
http://www.a.com/a.js http://www.b.com/b.js |
不同域名 | 不允許 |
什么是JSONP?
JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式,而JSONP(JSON with Padding)則是JSON 的一種“使用模式”,通過這種模式可以實(shí)現(xiàn)數(shù)據(jù)的跨域獲取。
JSONP跨域的原理
在同源策略下,在某個(gè)服務(wù)器下的頁面是無法獲取到該服務(wù)器以外的數(shù)據(jù)的,但img、iframe、script等標(biāo)簽是個(gè)例外,這些標(biāo)簽可以通過src屬性請(qǐng)求到其他服務(wù)器上的數(shù)據(jù)。利用script標(biāo)簽的開放策略,我們可以實(shí)現(xiàn)跨域請(qǐng)求數(shù)據(jù),當(dāng)然,也需要服務(wù)端的配合。當(dāng)我們正常地請(qǐng)求一個(gè)JSON數(shù)據(jù)的時(shí)候,服務(wù)端返回的是一串JSON類型的數(shù)據(jù),而我們使用JSONP模式來請(qǐng)求數(shù)據(jù)的時(shí)候,服務(wù)端返回的是一段可執(zhí)行的JavaScript代碼。
跨域: js有一個(gè)同源限制,簡(jiǎn)單說來源不一樣的話就無法相互間交互.那么怎么算來源不一樣呢, 舉個(gè)例子:瀏覽器訪問-->服務(wù)器A--->得到頁面A---頁面A中的js腳本只能訪問服務(wù)器A的資源(相同域名和端口,此外域名與對(duì)應(yīng)的ip也算不同源,要么都域名,要么都ip).
以上就是js的跨域問題,但是這里需要注意一點(diǎn)的是服務(wù)器A是沒有跨域的問題的,這個(gè)只有js存在這個(gè)問題,也就是說: 頁面A中js-->服務(wù)器A--->跨域資源,這個(gè)路徑是可以.只有 頁面A中的js--->跨域資源,這個(gè)路徑是不行的.
然后說一下解決方案中的jsonp,這個(gè)不是一種格式,而是一種解決方案.
jsonp的原理:js雖然有同源限制,但是引入js文件的時(shí)候卻沒有這個(gè)限制,也就是說:
<script type="text/javascript" src="xxx/xxxx.js"></script>
其中src屬性引入js文件的時(shí)候是沒有同源限制的,此時(shí)是可以引入域外資源的.jsonp的原理就在這里,通過動(dòng)態(tài)的創(chuàng)建一個(gè)以上那行js引入語句,通過其src屬性訪問域外資源.而域外資源服務(wù)器只要返回一個(gè)能被解析為js語句的字符串即可達(dá)到返回結(jié)果的目的,形如:
callback({"key":"value",...})
其中callback是需要事先約定的名字,綠字部分為要返回到j(luò)son字符串,然后拼接成以上那種形式直接返回即可.這樣頁面中的js從服務(wù)端接收到這個(gè)拼接的字符串后,就會(huì)直接執(zhí)行本地的名為callback的js方法,這也就是為何callback這個(gè)需要事先約定的原因,需要保證頁面?zhèn)纫嬖谶@個(gè)js方法,這個(gè)方法傳入的參數(shù)就為服務(wù)器側(cè)的返回值.
ajax是支持jsonp的,所以以上那些麻煩事情都會(huì)替我們做,寫法如下:
$.ajax({ type: 'GET', url: "http://127.0.0.1:8080/xxx/xxx", async: false, dataType: "jsonp", jsonp: "callback", success: function(result){ ..... }, timeout:3000 });
紅字部分標(biāo)識(shí)我們使用jsonp的方式調(diào)用,實(shí)際上此時(shí)這個(gè)已經(jīng)不是傳統(tǒng)意義上的ajax的get請(qǐng)求了,它的真實(shí)實(shí)現(xiàn)方式就是我們上文中說的那樣.其中紅字部分的callback為我們要和服務(wù)器端進(jìn)行溝通的部分,這個(gè)請(qǐng)求發(fā)送到服務(wù)器端,實(shí)際上這樣的:
http://127.0.0.1:8080/xxx/xxx?callback=jqueryxxxx
服務(wù)器端需要通過callback來取值(類似用request.getParameter("callback")),也就是取后面的jqueryxxxx等自動(dòng)生成的值,這個(gè)值實(shí)際上就是對(duì)應(yīng)的我們發(fā)送請(qǐng)求的ajax方法中的success回調(diào)方法,服務(wù)器端如果返回
jqueryxxxx({"ret":"ok"})
頁面中會(huì)自動(dòng)執(zhí)行success方法,且將{"ret":"ok"}傳給success方法的參數(shù)result.
以上就是ajax通過jsonp的方式實(shí)現(xiàn)跨域訪問的過程.可以看出基本不用我們做什么額外操作,全都封裝好了.
ps:在jQuery中如何通過JSONP來跨域獲取數(shù)據(jù)
第一種方法是在ajax函數(shù)中設(shè)置dataType為'jsonp':
$.ajax({ dataType: 'jsonp', url: 'http://www.a.com/user?id=123', success: function(data){ //處理data數(shù)據(jù) } });
第二種方法是利用getJSON來實(shí)現(xiàn),只要在地址中加上callback=?參數(shù)即可:
$.getJSON('http://www.a.com/user?id=123&callback=?', function(data){ //處理data數(shù)據(jù) });
也可以簡(jiǎn)單地使用getScript方法:
//此時(shí)也可以在函數(shù)外定義foo方法 function foo(data){ //處理data數(shù)據(jù) } $.getJSON('http://www.a.com/user?id=123&callback=foo');
JSONP的應(yīng)用
JSONP在開放API中可以起到非常重要的作用,開放API是運(yùn)用在開發(fā)者自己的應(yīng)用上,而許多應(yīng)用往往是在開發(fā)者的服務(wù)器上而不是在新浪微博的服務(wù)器上,因此跨域請(qǐng)求數(shù)據(jù)成為開發(fā)者們所需要解決的一大問題,廣大開放平臺(tái)應(yīng)該實(shí)現(xiàn)對(duì)JSONP的支持,這一點(diǎn)新浪微博開放平臺(tái)便做的非常好(雖然某些API里沒有說明,但實(shí)際上是可以使用JSONP方式調(diào)用的)。
- 原生js實(shí)現(xiàn)ajax請(qǐng)求和JSONP跨域請(qǐng)求操作示例
- 詳解Java Ajax jsonp 跨域請(qǐng)求
- AJAX跨域請(qǐng)求JSONP獲取JSON數(shù)據(jù)的實(shí)例代碼
- 通過jsonp獲取json數(shù)據(jù)實(shí)現(xiàn)AJAX跨域請(qǐng)求
- AJAX跨域請(qǐng)求之JSONP獲取JSON數(shù)據(jù)
- AJAX跨域請(qǐng)求json數(shù)據(jù)的實(shí)現(xiàn)方法
- 跨域請(qǐng)求之jQuery的ajax jsonp的使用解惑
- AJAX跨域請(qǐng)求獲取JSON數(shù)據(jù)的實(shí)現(xiàn)方法
相關(guān)文章
ajax異步處理POST表單中的數(shù)據(jù)示例代碼
這篇文章主要介紹了如何利用ajax異步處理POST表單中的數(shù)據(jù),下面有個(gè)不錯(cuò)的示例,大家可以參考下2014-06-06零基礎(chǔ)學(xué)習(xí)AJAX之AJAX框架
本文是零基礎(chǔ)學(xué)習(xí)AJAX系列教程的第二篇,我們介紹點(diǎn)不一樣的知識(shí),學(xué)習(xí)下ajaxLib和ajaxGold兩款框架,方便我們更好的理解ajax.2015-01-01jQuery實(shí)現(xiàn)AJAX定時(shí)刷新局部頁面實(shí)例
本篇文章通過兩種方法實(shí)例講解ajax定時(shí)刷新局部頁面,當(dāng)然方法有很多種,也可以不使用ajax來刷新頁面,可以使用jquery中的append來給指定內(nèi)容加?xùn)|西,但是都不太實(shí)用,最實(shí)用的方法還是ajax加載數(shù)據(jù)了。2015-09-09ajax回調(diào)函數(shù)參數(shù)傳遞正確方法
ajax回調(diào)函數(shù)參數(shù)傳遞正確方法,很多朋友習(xí)慣的寫錯(cuò)了,這里簡(jiǎn)單的小結(jié)下。2010-12-12AJax 把拿到的后臺(tái)數(shù)據(jù)在頁面中渲染的實(shí)例
今天小編就為大家分享一篇AJax 把拿到的后臺(tái)數(shù)據(jù)在頁面中渲染的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08ztree+ajax實(shí)現(xiàn)文件樹下載功能
這篇文章主要為大家詳細(xì)介紹了ztree+ajax實(shí)現(xiàn)文件樹下載功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05有關(guān)ajax的error與后臺(tái)的異常問題解決
這篇文章主要介紹了關(guān)于ajax的error與后臺(tái)的異常,需要的朋友可以參考下2014-02-02