跨域失敗

當使用jsonp跨域時,
1:請求必須是GET
2:python 寫的webservice返回的格式是JSONP格式,不是JSON格式。這里特別注意。

在這篇文章上看到
www.oschina.net/question/219762_142069


在這里找到了解決方案
json - JSONP web service with python - Stack Overflow

python寫的webservice是用flask框架寫的,適合新手用。

什么是跨域?
概念:只要協(xié)議、域名、端口有任何一個不同,都被當作是不同的域。
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://70.32.92.74/b.js 域名和域名對應(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 同一域名,不同二級域名(同上) 不允許(cookie這種情況下也不允許訪問)http://www.cnblogs.com/a.js
http://www.a.com/b.js 不同域名 不允許
對于端口和協(xié)議的不同,只能通過后臺來解決。
通過jsonp跨域
現(xiàn)在問題來了?什么是jsonp?維基百科的定義是:JSONP(JSON with Padding)是資料格式JSON的一種“使用模式”,可以讓網(wǎng)頁從別的網(wǎng)域要資料。
JSONP也叫填充式JSON,是應(yīng)用JSON的一種新方法,只不過是被包含在函數(shù)調(diào)用中的JSON,例如:
callback({"name","trigkit4"});
JSONP由兩部分組成:回調(diào)函數(shù)和數(shù)據(jù)?;卣{(diào)函數(shù)是當響應(yīng)到來時應(yīng)該在頁面中調(diào)用的函數(shù),而數(shù)據(jù)就是傳入回調(diào)函數(shù)中的JSON數(shù)據(jù)。
在js中,我們直接用XMLHttpRequest請求不同域上的數(shù)據(jù)時,是不可以的。但是,在頁面上引入不同域上的js腳本文件卻是可以的,jsonp正是利用這個特性來實現(xiàn)的。 例如:
functiondosomething(jsondata){//處理獲得的json數(shù)據(jù)}
js文件載入成功后會執(zhí)行我們在url參數(shù)中指定的函數(shù),并且會把我們需要的json數(shù)據(jù)作為參數(shù)傳入。所以jsonp是需要服務(wù)器端的頁面進行相應(yīng)的配合的。
最終,輸出結(jié)果為:dosomething(['a','b','c']);
如果你的頁面使用jquery,那么通過它封裝的方法就能很方便的來進行jsonp操作了。
$.getJSON('http://example.com/data.php?callback=?,function(jsondata)'){//處理獲得的json數(shù)據(jù)});
jquery會自動生成一個全局函數(shù)來替換callback=?中的問號,之后獲取到數(shù)據(jù)后又會自動銷毀,實際上就是起一個臨時代理函數(shù)的作用。$.getJSON方法會自動判斷是否跨域,不跨域的話,就調(diào)用普通的ajax方法;跨域的話,則會以異步加載js文件的形式來調(diào)用jsonp的回調(diào)函數(shù)。
JSONP的優(yōu)缺點
JSONP的優(yōu)點是:它不像XMLHttpRequest對象實現(xiàn)的Ajax請求那樣受到同源策略的限制;它的兼容性更好,在更加古老的瀏覽器中都可以運行,不需要XMLHttpRequest或ActiveX的支持;并且在請求完畢后可以通過調(diào)用callback的方式回傳結(jié)果。
JSONP的缺點則是:它只支持GET請求而不支持POST等其它類型的HTTP請求;它只支持跨域HTTP請求這種情況,不能解決不同域的兩個頁面之間如何進行JavaScript調(diào)用的問題。
CORS和JSONP對比
CORS與JSONP相比,無疑更為先進、方便和可靠。
1、 JSONP只能實現(xiàn)GET請求,而CORS支持所有類型的HTTP請求。
2、 使用CORS,開發(fā)者可以使用普通的XMLHttpRequest發(fā)起請求和獲得數(shù)據(jù),比起JSONP有更好的錯誤處理。
3、 JSONP主要被老的瀏覽器支持,它們往往不支持CORS,而絕大多數(shù)現(xiàn)代瀏覽器都已經(jīng)支持了CORS)。
CORS能做什么:
正常使用AJAX會需要正??紤]跨域問題,所以偉大的程序員們又折騰出了一系列跨域問題的解決方案,如JSONP、flash、ifame、xhr2等等。
本文介紹的CORS就是一套AJAX跨域問題的解決方案。
CORS的原理:
CORS定義一種跨域訪問的機制,可以讓AJAX實現(xiàn)跨域訪問。CORS 允許一個域上的網(wǎng)絡(luò)應(yīng)用向另一個域提交跨域 AJAX 請求。實現(xiàn)此功能非常簡單,只需由服務(wù)器發(fā)送一個響應(yīng)標頭即可。
CORS瀏覽器支持情況如下圖:

CORS啟航
假設(shè)我們頁面或者應(yīng)用已在http://www.test1.com上了,而我們打算從http://www.test2.com請求提取數(shù)據(jù)。一般情況下,如果我們直接使用 AJAX 來請求將會失敗,瀏覽器也會返回“源不匹配”的錯誤,"跨域"也就以此由來。
利用 CORS,http://www.test2.com只需添加一個標頭,就可以允許來自http://www.test1.com的請求,下圖是我在PHP中的 hander() 設(shè)置,“*”號表示允許任何域向我們的服務(wù)端提交請求:

也可以設(shè)置指定的域名,如域名http://www.test2.com,那么就允許來自這個域名的請求:

當前我設(shè)置的header為“*”,任意一個請求過來之后服務(wù)端我們都可以進行處理&響應(yīng),那么在調(diào)試工具中可以看到其頭信息設(shè)置,其中見紅框中有一項信息是“Access-Control-Allow-Origin:*”,表示我們已經(jīng)啟用CORS,如下圖。
PS:由于demo都在我廠的兩臺測試機間完成,外網(wǎng)也不能訪問,所以在這就不提供demo了,見諒


簡單的一個header設(shè)置,一個支持跨域&POST請求的server就完成了:)
當然,如果沒有開啟CORS必定失敗的啦,如下圖:
