CORS是一種允許當前域(domain)的資源(比如html/js/web service)被其他域(domain)的腳本請求訪問的機制,通常由於同域安全策略(the same-origin security policy)瀏覽器會禁止這種跨域請求。
CORS也有一些限制,兩種模型可以實現:
1.簡單模型
只支持getpost,不支持putdelete等,例如返回 Access-Control-Allow-Origin:*,但是不允許自定義header且會忽略cookies,且post數據格式有限制,只支持 ‘text/plain','application/x-www-urlencoded'and'multipart/form-data',其 中’text/plain'默認支持,后面兩種需要下面的預檢請求和服務器協商。
2.協商模型/預檢請求(Preflighted Request)
舉例:瀏覽器發出PUT請求,OPTION請求返回Access- Control-Allow-Origin:*,Access-Control-Allow-Methods:’PUT’,服務器同意所有域的PUT請 求,瀏覽器收到並繼續發出真正的PUT請求,服務器響應並再次返回Access-Control-Allow-Origin:*,允許瀏覽器的腳本執行服 務器返回的數據。
地址 http://www.yiichina.com/doc/guide/2.0/structure-filters
yii\filters\Cors
跨域資源共享 CORS 機制允許一個網頁的許多資源(例如字體、JavaScript等) 這些資源可以通過其他域名訪問獲取。 特別是JavaScript's AJAX 調用可使用 XMLHttpRequest 機制,由於同源安全策略該跨域請求會被網頁瀏覽器禁止. CORS定義瀏覽器和服務器交互時哪些跨域請求允許和禁止。
yii\filters\Cors 應在 授權 / 認證 過濾器之前定義,以保證CORS頭部被發送。
use yii\filters\Cors; use yii\helpers\ArrayHelper; public function behaviors() { return ArrayHelper::merge([ [ 'class' => Cors::className(), ], ], parent::behaviors()); }
Cors 可轉為使用 cors
屬性。
cors['Origin']
: 定義允許來源的數組,可為['*']
(任何用戶) 或['http://www.myserver.net', 'http://www.myotherserver.com']
. 默認為['*']
.cors['Access-Control-Request-Method']
: 允許動作數組如['GET', 'OPTIONS', 'HEAD']
. 默認為['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']
.cors['Access-Control-Request-Headers']
: 允許請求頭部數組,可為['*']
所有類型頭部 或['X-Request-With']
指定類型頭部. 默認為['*']
.cors['Access-Control-Allow-Credentials']
: 定義當前請求是否使用證書,可為true
,false
或null
(不設置). 默認為null
.cors['Access-Control-Max-Age']
: 定義請求的有效時間,默認為86400
.
例如,允許來源為 http://www.myserver.net
和方式為 GET
, HEAD
和 OPTIONS
的CORS如下:
use yii\filters\Cors; use yii\helpers\ArrayHelper; public function behaviors() { return ArrayHelper::merge([ [ 'class' => Cors::className(), 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], ], ], ], parent::behaviors()); }
可以覆蓋默認參數為每個動作調整CORS 頭部。例如,為login
動作增加Access-Control-Allow-Credentials
參數如下所示:
use yii\filters\Cors; use yii\helpers\ArrayHelper; public function behaviors() { return ArrayHelper::merge([ [ 'class' => Cors::className(), 'cors' => [ 'Origin' => ['http://www.myserver.net'], 'Access-Control-Request-Method' => ['GET', 'HEAD', 'OPTIONS'], ], 'actions' => [ 'login' => [ 'Access-Control-Allow-Credentials' => true, ] ] ], ], parent::behaviors()); }