远程服务器上的 YII 2 REST CORS 问题
YII 2 REST CORS issue on remote server
我开发了一个 Yii2 REST API 应用程序。在本地一切正常。
我已将应用程序部署到远程服务器。我可以通过 Postman 获得 api 回复。但是当我尝试使用 AJAX 或 Angular 发出请求时,我收到 "Response for preflight has invalid HTTP status code 401" 错误。
我的控制器行为()方法:
public function behaviors() {
return array_merge(parent::behaviors(), [
$behaviors['corsFilter'] = [
'class' => \yii\filters\Cors::className(),
'cors' => [
// restrict access to domains:
'Origin' => ['*'],
'Access-Control-Request-Method' => ['GET','POST','PUT','DELETE','OPTIONS'],
'Access-Control-Request-Headers' => ['*'],
'Access-Control-Allow-Credentials' => true,
'Access-Control-Max-Age' => 3600, // Cache (seconds)
],
],
$behaviors['authenticator'] = [
'class' => AvnrHttpBasicAuth::className(),
],
]);
}
响应和请求Headers:
我认为这是 CORS 问题,但我无法弄清楚为什么这在带有 apache 的 Centos 上的远程服务器 运行 上不起作用。
我扩展了 HttpBasicAuth 并使用了我自己的 AvnrHttpBasicAuth class
class AvnrHttpBasicAuth extends HttpBasicAuth
{
public function authenticate($user, $request, $response)
{
$authHeader = $request->getHeaders()->get('Authorization');
if ($authHeader !== null && preg_match("/^Basic\s+(.*?)$/", $authHeader, $matches)) {
$identity = $user->loginByAccessToken($matches[1], get_class($this));
if ($identity === null) {
$this->handleFailure($response);
}
return $identity;
}
return null;
}
}
您需要为预检请求添加例外,如 official docs 所示:
$behaviors['authenticator'] = [
'class' => AvnrHttpBasicAuth::className(),
'except' => ['options']
],
Preflight Requests 是浏览器在需要时 handled/issued。例如,当前端和后端托管在不同域中并且您正在发出 POST 请求时,浏览器需要先发送一个 OPTIONS 请求以查看是否允许 POST,然后再发送真实请求。要从 POSTMAN 测试它,您需要发送 OPTIONS 请求而不是 POST/PUT.
我通过对我的 .htaccess 文件稍作修改解决了这个问题。
多亏了这个post
.htaccess 文件中下面的这两行起到了作用。
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ [R=200,L]
Header always set Access-Control-Allow-Origin "*"
我开发了一个 Yii2 REST API 应用程序。在本地一切正常。 我已将应用程序部署到远程服务器。我可以通过 Postman 获得 api 回复。但是当我尝试使用 AJAX 或 Angular 发出请求时,我收到 "Response for preflight has invalid HTTP status code 401" 错误。 我的控制器行为()方法:
public function behaviors() {
return array_merge(parent::behaviors(), [
$behaviors['corsFilter'] = [
'class' => \yii\filters\Cors::className(),
'cors' => [
// restrict access to domains:
'Origin' => ['*'],
'Access-Control-Request-Method' => ['GET','POST','PUT','DELETE','OPTIONS'],
'Access-Control-Request-Headers' => ['*'],
'Access-Control-Allow-Credentials' => true,
'Access-Control-Max-Age' => 3600, // Cache (seconds)
],
],
$behaviors['authenticator'] = [
'class' => AvnrHttpBasicAuth::className(),
],
]);
}
响应和请求Headers:
我认为这是 CORS 问题,但我无法弄清楚为什么这在带有 apache 的 Centos 上的远程服务器 运行 上不起作用。
我扩展了 HttpBasicAuth 并使用了我自己的 AvnrHttpBasicAuth class
class AvnrHttpBasicAuth extends HttpBasicAuth
{
public function authenticate($user, $request, $response)
{
$authHeader = $request->getHeaders()->get('Authorization');
if ($authHeader !== null && preg_match("/^Basic\s+(.*?)$/", $authHeader, $matches)) {
$identity = $user->loginByAccessToken($matches[1], get_class($this));
if ($identity === null) {
$this->handleFailure($response);
}
return $identity;
}
return null;
}
}
您需要为预检请求添加例外,如 official docs 所示:
$behaviors['authenticator'] = [
'class' => AvnrHttpBasicAuth::className(),
'except' => ['options']
],
Preflight Requests 是浏览器在需要时 handled/issued。例如,当前端和后端托管在不同域中并且您正在发出 POST 请求时,浏览器需要先发送一个 OPTIONS 请求以查看是否允许 POST,然后再发送真实请求。要从 POSTMAN 测试它,您需要发送 OPTIONS 请求而不是 POST/PUT.
我通过对我的 .htaccess 文件稍作修改解决了这个问题。 多亏了这个post
.htaccess 文件中下面的这两行起到了作用。
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ [R=200,L]
Header always set Access-Control-Allow-Origin "*"