我开发了一个Yii2 REST API应用程序。当地的一切都很好。 我已将应用程序部署到远程服务器。我可以通过Postman获得api回复。但是当我尝试用AJAX或Angular发出请求时,我得到“预检的响应有无效的HTTP状态代码401”错误。 我的Controller behavior()方法:
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(),
],
]);
}
响应和请求标头:
我认为这是CORS问题,但我无法弄清楚为什么这不适用于使用apache在Centos上运行的远程服务器。
我已经扩展了HttpBasicAuth并使用了我自己的AvnrHttpBasicAuth类
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;
}
}
答案 0 :(得分:1)
您需要为预检请求添加例外,如official docs:
所示$behaviors['authenticator'] = [
'class' => AvnrHttpBasicAuth::className(),
'except' => ['options']
],
Preflight Requests由浏览器在需要时处理/发布。例如,当前端和后端托管在不同的域中并且您正在发出POST请求时,浏览器需要首先发送OPTIONS请求以查看在发送真实的POST之前是否允许POST。要从POSTMAN测试它,您需要发送OPTIONS请求而不是POST / PUT。
答案 1 :(得分:1)
我通过对.htaccess文件的一个小修改解决了这个问题。 感谢post
.htaccess文件中的这两行完成了这一操作。
@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpModule,
MovieModule
],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {
}