以下这个问题我将我的休息控制器行为设置为
public function behaviors() { $behaviors = parent::behaviors(); $auth= $behaviors['authenticator'] = [ 'class' => HttpBearerAuth::className(), 'only' => ['dashboard'], ]; $behaviors['contentNegotiator'] = [ 'class' => ContentNegotiator::className(), 'formats' => [ 'application/json' => Response::FORMAT_JSON, ], ]; $acces=$behaviors['access'] = [ 'class' => AccessControl::className(), 'only' => ['login'], 'rules' => [ [ 'actions' => ['login'], 'allow' => true, 'roles' => ['?'], ], ], ]; unset($behaviors['authenticator']); unset($behaviors['access']);
现在,cors过滤器
// add CORS filter $behaviors['corsFilter'] = [ 'class' => \yii\filters\Cors::className(), 'cors' => [ // restrict access to 'Access-Control-Allow-Origin' => ['*'], 'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'], // Allow only POST and PUT methods 'Access-Control-Request-Headers' => ['*'], // Allow only headers 'X-Wsse' 'Access-Control-Allow-Credentials' => true, // Allow OPTIONS caching 'Access-Control-Max-Age' => 86400, // Allow the X-Pagination-Current-Page header to be exposed to the browser. 'Access-Control-Expose-Headers' => [], ] ]; // re-add authentication filter $behaviors['authenticator'] = $auth; $behaviors['access'] = $access; // avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method) $behaviors['authenticator']['except'] = ['options']; return $behaviors; }
我的angular2前端是
const body = JSON.stringify(user); let headers = new Headers(); headers.append('Content-Type', 'application/x-www-form-urlencoded'); headers.append('Content-Type', 'application/json'); headers.append('Access-Control-Allow-Credentials', "*"); return this._http.post(this.loginUrl, body, { headers:headers }) .map((response: Response) => { //process response }) .catch(this.handleError);
但我仍然得到一个错误
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
什么可能是错的,因为我在yii2行为中设置cors过滤器取消设置身份验证器并在以后添加它我可能会错过什么
我还检查了该链接,也这一个 ,但没有解决问题
如果CORS标头出现任何问题,我建议使用以下说明:
将cors配置添加到控制器.例如:
/** * 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-headers.使用浏览器调试工具检查http-headers:
请求http标头应包含Origin
.它将由浏览器自动添加到Crossdomain AJAX.这个http-header也可以通过你的JS库添加.没有这个http-header corsFilter
将无法正常工作.
POST /api/some-method-name HTTP/1.1 Host: api.example.com Connection: keep-alive Content-Length: 86 Accept: */* Origin: https://my-site.example.com User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Referer: https://my-site.example.com/ Accept-Encoding: gzip, deflate, br Accept-Language: en-GB,en;q=0.8,en-US;q=0.6,ru;q=0.4
响应http标头应包含Access-Control-*
标头.这个http标题将被添加corsFilter
.
HTTP/1.1 200 OK Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: https://my-site.example.com Content-Type: application/json; charset=UTF-8 Date: Fri, 24 Feb 2017 09:21:47 GMT Server: Apache Content-Length: 27 Connection: keep-alive
如果您没有看到这些http标头作为响应,可能意味着它\yii\filters\Cors
不起作用.
检查控制器中的其他行为/过滤器.尝试添加corsFilter
为第一个行为.可能一些其他行为会阻止执行corsFilter
.
尝试禁用此控制器的CSRF验证(可能会阻止外部访问):
/** * Controller for API methods. */ class ApiController extends Controller { /** * @var bool See details {@link \yii\web\Controller::$enableCsrfValidation}. */ public $enableCsrfValidation = false; // ... }
另外应检查您的Web服务器.可能nginx可能需要额外配置,apache可能需要重启.
Access-Control-*
可以使用web-server添加响应中的标头(请参阅apache和nginx).但我不建议使用这种方式,因为在这种情况下,您无法使用应用程序管理http-haders.
一些有用的信息可以在这里找到:
Yii2:如何在非restfull API上允许CORS