Yii2:如何在非restfull API上允许CORS [英] Yii2: How to allow CORS on non-restfull API
问题描述
我正在使用Yii2 Framework上的预构建API(不是restfull).它使用JSON数据进行响应,并根据用户类型和凭证令牌接受请求.现在,我必须制作一个在其他位置(域)上的应用程序,这会导致CORS冲突.
I am working with a pre-built API (not restfull) on Yii2 Framework. It responds with JSON data and accepts requests depending on User type and credential token. Now I have to make an app that is on a different location (domain) which is causing CORS conflict.
我的应用程序是jQuery,我正在使用$.ajax
进行数据发送和接收.
如何避免这种CORS冲突并通过ajax使用API?
My app is jQuery and I'm using $.ajax
for data sending and receiving.
How can I avoid this CORS conflict and use the API over ajax?
致谢
更新:
正如IStranger在回答中告诉我的那样,我添加了以下代码:
As IStranger told me in his answer I added the following code:
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
可能是个问题吗?
But I am still getting the error. There is a beforeAction
in the code can that be a problem?
这是RAW HEADER
This is the RAW HEADER
请求:
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
推荐答案
只需添加到您的API控制器:
Just add to your API controller:
/**
* 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)
],
],
]);
}
此代码将添加到响应特殊的HTTP标头中.请求http标头应具有Origin
(它将由浏览器自动在Crossdomain AJAX中添加).响应http标头应具有Access-Control-*
标头.
This code will add to response special http-headers. Request http header should haves Origin
(it will be added by browser automatically at Crossdomain AJAX). Response http headers should have Access-Control-*
headers.
注意::如果您没有在响应中看到这些http标头,则可能表示\yii\filters\Cors
不起作用.检查控制器中的其他行为/过滤器.尝试对此控制器禁用CSRF验证(这可能会阻止外部访问):
NOTE: If you don't see these http headers in response, probably it means that \yii\filters\Cors
don't works. Check other behaviors/filters in controller. Try to disable CSRF validation for this controller (it may prevent external access):
/**
* Controller for API methods.
*/
class ApiController extends Controller
{
/**
* @var bool See details {@link \yii\web\Controller::$enableCsrfValidation}.
*/
public $enableCsrfValidation = false;
// ...
}
UPD :还应检查您的网络服务器.可能nginx可能需要其他配置,而apache可能需要重新启动.
UPD: Additionally should be checked your web-server. Probably nginx may require additional configuration, apache can require restarting.
UPD2:此处更完整的说明: https://stackoverflow.com/a/42435695/3793592
UPD2: More complete instruction here: https://stackoverflow.com/a/42435695/3793592
这篇关于Yii2:如何在非restfull API上允许CORS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!