AJAX POST&跨域 解決方案 - CORS
2014-01-06 09:09 聶微東 閱讀(249346) 評(píng)論(29) 收藏 舉報(bào) 一晃又到新年了,于是開(kāi)始著手好好整理下自己的文檔,順便把一些自認(rèn)為有意義的放在博客上,記錄成點(diǎn)的點(diǎn)滴。

跨域是我在日常面試中經(jīng)常會(huì)問(wèn)到的問(wèn)題,這詞在前端界出現(xiàn)的頻率不低,主要原因還是由于安全限制(同源策略, 即JavaScript或Cookie只能訪(fǎng)問(wèn)同域下的內(nèi)容),因?yàn)槲覀冊(cè)谌粘5捻?xiàng)目開(kāi)發(fā)時(shí)會(huì)不可避免的需要進(jìn)行跨域操作,所以跨域能力也算是前端工程師的基本功之一。
和大多數(shù)跨域的解決方案一樣,JSONP也是我的選擇,可是某天PM的需求變了,某功能需要改成支持POST,因?yàn)閭鬏數(shù)臄?shù)據(jù)量比較大,GET形式搞不定。所以折騰了下聞名已久的CORS(跨域資源共享,Cross-Origin Resource Sharing),這邊文章也就是折騰期間的小記與總結(jié)。

概述
- CORS能做什么:
正常使用AJAX會(huì)需要正常考慮跨域問(wèn)題,所以偉大的程序員們又折騰出了一系列跨域問(wèn)題的解決方案,如JSONP、flash、ifame、xhr2等等。
本文介紹的CORS就是一套AJAX跨域問(wèn)題的解決方案。
- CORS的原理:
CORS定義一種跨域訪(fǎng)問(wèn)的機(jī)制,可以讓AJAX實(shí)現(xiàn)跨域訪(fǎng)問(wèn)。CORS 允許一個(gè)域上的網(wǎng)絡(luò)應(yīng)用向另一個(gè)域提交跨域 AJAX 請(qǐng)求。實(shí)現(xiàn)此功能非常簡(jiǎn)單,只需由服務(wù)器發(fā)送一個(gè)響應(yīng)標(biāo)頭即可。
- CORS瀏覽器支持情況如下圖:


喜聞樂(lè)見(jiàn)、普大喜奔的支持情況,尤其是在移動(dòng)終端上,除了opera Mini;
PC上的現(xiàn)代瀏覽器都能友好的支持,除了IE9-,不過(guò)前端工程師對(duì)這種情況早應(yīng)該習(xí)慣了...

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


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

簡(jiǎn)單的一個(gè)header設(shè)置,一個(gè)支持跨域&POST請(qǐng)求的server就完成了:)
當(dāng)然,如果沒(méi)有開(kāi)啟CORS必定失敗的啦,如下圖:

問(wèn)題&小結(jié)
- 剛剛說(shuō)到的兼容性。CORS是W3C中一項(xiàng)較新的方案,所以部分瀏覽器還沒(méi)有對(duì)其進(jìn)行支持或者完美支持,詳情可移至 http://www.w3.org/TR/cors/
- 安全問(wèn)題。CORS提供了一種跨域請(qǐng)求方案,但沒(méi)有為安全訪(fǎng)問(wèn)提供足夠的保障機(jī)制,如果你需要信息的絕對(duì)安全,不要依賴(lài)CORS當(dāng)中的權(quán)限制度,應(yīng)當(dāng)使用更多其它的措施來(lái)保障,比如OAuth2。
自認(rèn)為的cors使用場(chǎng)景:
- cors在移動(dòng)終端支持的不錯(cuò),可以考慮在移動(dòng)端全面嘗試;PC上有不兼容和沒(méi)有完美支持,所以小心踩坑。當(dāng)然瀏覽器兼容就是個(gè)偽命題,說(shuō)不準(zhǔn)某個(gè)瀏覽器的某個(gè)版本就完美兼容了,說(shuō)不準(zhǔn)就有點(diǎn)小坑,尼瑪傷不起!~
- jsonp是get形式,承載的信息量有限,所以信息量較大時(shí)CORS是不二選擇;
- 配合新的JSAPI(fileapi、xhr2等)一起使用,實(shí)現(xiàn)強(qiáng)大的新體驗(yàn)功能。
如果覺(jué)得這文章也算用心,請(qǐng)勞駕點(diǎn)右下角的推薦。
祝2014順利。
最后,有 北京&上海 的朋友想春節(jié)后想換工作的,【百度移動(dòng)云事業(yè)部】期待聰明、勤奮的你 與我聯(lián)系 (JD在頁(yè)面右上角)
參考資料:
浙公網(wǎng)安備 33010602011771號(hào)