国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
為 RESTful API 配置 CORS 實(shí)現(xiàn)跨域請(qǐng)求

 利用 Ruby on Rails 可以很方便地實(shí)現(xiàn) RESTful API,但如果我們需要通過(guò) AJAX 跨域調(diào)用的話,怎么辦?

說(shuō)到 AJAX 跨域,很多人最先想到的是 JSONP。的確,JSONP 我們已經(jīng)十分熟悉,也使用了多年,從本質(zhì)上講,JSONP 的原理是給頁(yè)面注入一個(gè) <script>,把遠(yuǎn)程 JavaScript 放在頁(yè)面上執(zhí)行。這種做法會(huì)帶來(lái)一個(gè)顯而易見的問(wèn)題:如果調(diào)用的來(lái)源被攻擊或篡改,那什么東西都可以注入到頁(yè)面里,造成 XSS 漏洞。另外,JSONP 本質(zhì)上已經(jīng)不是 XMLHttpRequest,所以在錯(cuò)誤處理上也沒(méi)有什么選擇。而且 JSONP 只支持 GET 請(qǐng)求,所以 RESTful API 就沒(méi)辦法了。

這也就是為什么我們需要 CORS。CORS 是 Cross Origin Resource Sharing 的縮寫,定義了瀏覽器和服務(wù)器間共享內(nèi)容的新方式,通過(guò)它瀏覽器和服務(wù)器可以安全地進(jìn)行跨域訪問(wèn),它是 JSONP 的現(xiàn)代繼任者。服務(wù)器上的 CORS 配置可以精細(xì)地指定允許跨域訪問(wèn)的條件:來(lái)源域、HTTP 方法、請(qǐng)求頭、內(nèi)容類型……等等。并且,CORS 讓 XMLHttpRequest 也可以跨域,我們可以像往常一樣編寫 AJAX 調(diào)用代碼。

所有現(xiàn)代瀏覽器都支持 CORS,所以你應(yīng)該可以放心地使用它,只有在需要兼容老舊瀏覽器的場(chǎng)合,才用 JSONP 做 fallback。

支持 CORS 的瀏覽器在嘗試進(jìn)行跨域 XMLHttpRequest 時(shí),會(huì)先發(fā)出一個(gè)“事前檢查”,就是一個(gè) OPTIONS請(qǐng)求,其中會(huì)包括一些有用的請(qǐng)求頭:

Access-Controll-Request-Headers: accept, content-typeAccess-Controll-Request-Method: POST

接著服務(wù)器會(huì)做出響應(yīng):

Access-Control-Allow-Origin: *Access-Control-Allow-Methods: POST, GET, OPTIONSAccess-Control-Allow-Headers: X-Requested-With, Content-Type, AcceptAccess-Control-Max-Age: 1728000

最后瀏覽器會(huì)根據(jù)服務(wù)器的響應(yīng)頭,判斷請(qǐng)求是否在服務(wù)器規(guī)定的范圍內(nèi)。比如來(lái)源是否在 Access-Control-Allow-Origin 里,HTTP 方法是不是在 Access-Control-Allow-Methods 里面,有沒(méi)有不在 Allow-Headers 里面的請(qǐng)求頭。如果以上條件都符合,那么瀏覽器就會(huì)放行這次請(qǐng)求,并且在 Access-Control-Max-Age 指定的時(shí)間內(nèi)(單位是秒,以上設(shè)置的是 20 天)不需要再進(jìn)行這種“事前檢查”。

在以上服務(wù)器響應(yīng)頭中,Access-Control-Allow-Headers 不可以使用通配符。所以如果你要允許所有請(qǐng)求頭,不妨把瀏覽器發(fā)來(lái)的 Access-Control-Request-Headers 直接返回。

事實(shí)上,如果跨域請(qǐng)求是“簡(jiǎn)單請(qǐng)求”,也就是 HTTP 方法為 GET、HEAD、POST,請(qǐng)求體的 MIME Type 是以下其中一種:application/x-www-form-urlencodedmultipart/form-data 或者 text/plain,并且沒(méi)有自定義的請(qǐng)求頭。這時(shí)瀏覽器只根據(jù)請(qǐng)求頭中的 Origin 和服務(wù)器返回的 Access-Control-Allow-Origin 就可以判斷了。但我們是 RESTful API,請(qǐng)求體是 application/json,所以只能用上面那種“事前檢查”的方式。

另外,利用 CORS 還可以在跨域請(qǐng)求中發(fā)送 Cookie,這個(gè)特性是很有用的。只需要為 XMLHttpRequest 對(duì)象設(shè)置 withCredentials 屬性:

var xhr = new XMLHttpRequest();xhr.withCredentials = true;

但這種情況下,就不能指定 Access-Control-Allow-Origin: *,而是必須指定一個(gè)來(lái)源,比如 http://mydomain.com。

下面來(lái)說(shuō)說(shuō)在服務(wù)器端怎么配置,以 Rails 框架為例。注意:這只是一個(gè)很簡(jiǎn)單的例子,為了展示其原理,建議只在安全要求不高的項(xiàng)目上使用這種方法。Rails 有專門的 Rack CORS 中間件可以處理這個(gè)問(wèn)題。

在一個(gè) Controller(或者 application_controller.rb )中添加 before_filter 和 after_filter。前者用來(lái)回應(yīng)瀏覽器的“事前檢查”,如果瀏覽器發(fā)來(lái)了 OPTIONS 請(qǐng)求,則返回一些響應(yīng)頭,并結(jié)束處理;后者則用來(lái)給響應(yīng)添加 CORS 的響應(yīng)頭:

# some_controller.rbbefore_filter :cors_preflight_checkafter_filter :cors_set_headers# ...def cors_preflight_check  if request.method == 'OPTIONS'    headers['Access-Controll-Allow-Origin'] = '*'    headers['Access-Controll-Allow-Methods'] = 'POST, GET, OPTIONS'    headers['Access-Controll-Allow-Headers'] = 'X-Requested-With, Content-Type, Accept'    headers['Access-Controll-Max-Age'] = '1728000'    render :text => '', :content-type => 'text/plain'  endenddef cors_set_headers  headers['Access-Controll-Allow-Origin'] = '*'  headers['Access-Controll-Allow-Methods'] = 'POST, GET, OPTIONS'  headers['Access-Controll-Max-Age'] = '1728000'end

最后,別忘了在 routes.rb 中允許 OPTIONS 請(qǐng)求:

match 'controller', to: 'controller#action', via: [:options] # 添加此行resources :controller
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
IIS 支持 ajax 跨域
Python學(xué)習(xí)教程:Python的cors跨域模塊主要做了什么?
PHP解決跨域問(wèn)題,加入header頭
Ajax跨域、Json跨域、Socket跨域和Canvas跨域等同源策略限制的解決方法
記錄我開發(fā)工作中遇到HTTP跨域和OPTION請(qǐng)求的一個(gè)坑
jfinal里使用ajax,jfinal解決ajax跨域問(wèn)題
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服