跨域GET、POST請求的小結
重點:跨域POST大量數據;
JQuery:$.ajax/$.getJSON支持jsonp格式的跨域,但是只支持GET方式,暫不支持POST;
CORS:w3c關於跨域的新方案,res.setHeader('Access-Control-Allow-Origin','*'),兼容IE9+;
so,跨域POST是個值得研究的問題啊!萬能的JQuery無法跨域POST;鑒於基本國情,CORS也只是適合在移動端玩玩;
相信有同學這樣做過:
1 $.ajax({
2 type: 'post',
3 url: url,
4 data: {a:1,b:2},
5 dataType: "jsonp",
6 crossDomain: true,
7 jsonpCallback: "sucCallback",
8 success: function (data) {
9 console.log(data);
10 },
11 error: function (data) {
12 console.log(data);
13 }
14 });
實際上chrome的控制台顯示卻是這樣的:

那么,如圖是否可以證明jQuery確實無法跨域POST呢?說好的POST呢,jQuery自動將其轉為GET了;這樣其實就和$.getJSON差不多了,只是$.ajax的跨域直接能回調返回值,而$.getJSON的返回值需要一個全局的callback(可自定義);
話說我的個人小站在移動端還處於最原始的縮放狀態,說好的H5 Response Web呢?原諒我再一次跑偏了:原本計划<link rel="stylesheets" type="css/text" media="screen and (max-width:xx-px)" href="max-xx.css" />或者直接在原有樣式表里media query;而結果卻是我新開了個站點,作為移動端的版本,讀取PC端存儲的數據;一方面減輕代碼量,使移動端更輕量簡潔,畢竟只是個博客嘛;另一方面,這樣的話,移動端將有更寬廣的隨意揮灑的空間;再者,基於性能優化,這樣也不錯;當然,問題也很明顯了;兩個站點要共享數據,連同一個數據庫,要做同步操作,呵呵,我一個小前端,這些貌似目前想太多啊!那么怎么辦呢,是的,就是上面說到的問題,前端跨域請求數據;
移動端的庫用的是由zepto的一些模塊自定義組裝的一個版本,bootstrap什么的一邊涼快涼快吧,樣式手寫的,權當練手吧。。。在后端,由Nodejs的http-proxy做代理,判斷請求的UA,如果是移動端的訪問,則無論host是www.famanoder.com還是m.famanoder.com全都分發到移動端的站點處理,這樣在手機上訪問http://www.famanoder.com就不用做跳轉了;
OK,那么要開始跨域請求和提交數據了;如果只是請求遠程數據,GET方式足矣;可是如果要提交大量數據,比如,某大俠路過小站,一時興起,引經據典,古今中外,滔滔不絕,長篇大論一通,這樣的話恐怕GET搞不定啊!先看看最簡單的GET方式吧:
1 $.getJSON('http://www.famanoder.com /page/ajaxPage?callback=?&jsonpCallback=getmore&page=3&ori=about');
然后定義好全局的getmore就OK了,后端處理也簡單,我這是Nodejs,其他的自行百度吧:
1 Artical.find({},function(err,docs){
2 err&&console.log(err);
3 var d=JSON.stringify(docs);
4 res.send(callback+"("+d+")");
5 });
當然像上圖里那樣也是可以的,后端同樣處理;
前面說了,偉大的JQuery暫時不支持POST方式的跨域;那咋辦呢?其實沒有想象的那么復雜,是時候證明你不能太依賴JQuery了,有時候沒有她,你也要好好過;
基本原理大概是這樣的:form表單提交,無論你是post,還是get,無論你提交到哪,只要后端有對應程序處理,都妥妥的,不存在跨域一說;以前無刷新上傳、提交表單都是將form的target指向一個空iframe,此處同理;類似:a.com提交表單到b.com,表單的target為一個空iframe;b.com處理請求,在response里執行callback,注意,此處callback是屬於那個空iframe的;
1 <!-- a.html --> 2 <!-- test post access domain --> 3 <!-- use form and hide iframe --> 4 <form action="b.com" method="post" target="hidefrm"> 5 <input type="text" value="test post data access domain"> 6 <input type="submit" value="submit"> 7 </form> 8 <iframe src="" name="hidefrm" frameborder="0"></iframe>
后端的處理基本一樣;如果不出意料,到此,請求會在控制台出現一片紅,是的,要你設置domain;除了頁面和對應js要設置domain外,一定別忘啦,response里的callback其實是屬於當前頁面的,所以response里執行的callback也要設置domain;類似這樣:
1 res.send('document.domain="a.com";window.parent.aa('+str+')');
OK,沒有了她,你依然要好好過;這樣你就可以POST跨域提交大量數據了;同時也彌補了JQuery只能通過jsonp GET跨域了;當然CORS在移動端也是值得推薦的;小伙伴們可以試一下,或者有其他什么好辦法,記得和我分享啊!

