2016-09-22 66 views
4

我正在使用Yii2 Framework上的預構建API(不是restfull)。它響應JSON數據並接受取決於用戶類型和憑證令牌的請求。現在我必須創建一個位於不同位置(域)的應用程序,這會導致CORS衝突。Yii2:如何允許在非restfull API上使用CORS

我的應用程序是jQuery,我使用$.ajax進行數據發送和接收。 我該如何避免這種CORS衝突,並通過ajax使用API​​?

問候

UPDATE:

由於IStranger告訴我,在他的回答,我添加以下代碼:

public function behaviors() 
{ 
    $behaviors = parent::behaviors(); 
    $behaviors['corsFilter'] = [ 
     'class' => \yii\filters\Cors::className(), 
     'cors' => [ 
      'Origin'       => "*", 
      'Access-Control-Request-Method' => ['POST', 'GET'], 
      'Access-Control-Allow-Credentials' => true, 
      'Access-Control-Max-Age'   => 3600, 
     ], 
    ]; 
    return $behaviors; 
} 

但我仍然得到錯誤。在代碼中有一個beforeAction可以是一個問題?

這是RAW頭

請求:

Host: domain.com 
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:48.0) Gecko/20100101 Firefox/48.0 
Accept: */* 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Referer: http://localhost/main/main.html 
Content-Length: 296 
Origin: http://localhost 
Connection: keep-alive 

響應:

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 
Connection: Keep-Alive 
Content-Length: 101 
Content-Type: application/json; charset=UTF-8 
Date: Thu, 22 Sep 2016 17:23:48 GMT 
Expires: Thu, 19 Nov 1981 08:52:00 GMT 
Keep-Alive: timeout=5, max=100 
Pragma: no-cache 
Server: Apache/2.4.17 (Win64) PHP/5.6.16 
Set-Cookie: PHPSESSID=ph0b322gbq65m1f3m8fp9fphc0; path=/; HttpOnly 
X-Powered-By: PHP/5.6.16 
+0

嘗試更換' '起源'=> [ 「*」],'。 然後使用瀏覽器調試器(「網絡」選項卡)檢查AJAX請求的http頭。請求標頭應該有'Origin'值,並且響應標頭應該有'Access-Control-Allow-Credentials'和'Access-Control-Allow-Origin'。 – IStranger

+0

@ISTRANK確定工作,但現在我得到一個500錯誤,但與請求類型的選項,因爲我在發佈 –

+0

@ISTRAGER忽略我的最後一條評論,它仍然無法正常工作。 –

回答

4

只需添加到您的API控制器:

/** 
* List of allowed domains. 
* Note: Restriction works only for AJAX (using CORS, is not secure). 
* 
* @return array List of domains, that can access to this API 
*/ 
public static function allowedDomains() 
{ 
    return [ 
     // '*',      // star allows all domains 
     'http://test1.example.com', 
     'http://test2.example.com', 
    ]; 
} 

/** 
* @inheritdoc 
*/ 
public function behaviors() 
{ 
    return array_merge(parent::behaviors(), [ 

     // For cross-domain AJAX request 
     'corsFilter' => [ 
      'class' => \yii\filters\Cors::className(), 
      'cors' => [ 
       // restrict access to domains: 
       'Origin'       => static::allowedDomains(), 
       'Access-Control-Request-Method' => ['POST'], 
       'Access-Control-Allow-Credentials' => true, 
       'Access-Control-Max-Age'   => 3600,     // Cache (seconds) 
      ], 
     ], 

    ]); 
} 

此代碼將增加反應規範al http-headers。請求http頭部應該有Origin(它將由Crossdomain AJAX自動添加到瀏覽器中)。響應http標頭應該有Access-Control-*標頭。

注意:如果您沒有看到這些http標題作爲迴應,可能意味着\yii\filters\Cors不起作用。檢查控制器中的其他行爲/過濾器。嘗試禁用CSRF驗證該控制器(可以防止外部訪問):

/** 
* Controller for API methods. 
*/ 
class ApiController extends Controller 
{ 

    /** 
    * @var bool See details {@link \yii\web\Controller::$enableCsrfValidation}. 
    */ 
    public $enableCsrfValidation = false; 

    // ... 
} 

UPD:另外應檢查你的web服務器。可能nginx可能需要額外的配置,Apache可能需要重新啓動。

UPD2:更完整的指令位置:https://stackoverflow.com/a/42435695/3793592

+0

我在編輯有關您的答案的問題請參閱。 –

+0

我已經禁用了CSRF。 –

+0

我重新啓動了Apache並運行。我猜apache的緩存或什麼使問題持續存在。 –

相關問題