Post Request 在 Postman 中工作,但在 Angular 2 应用程序中返回 Preflight 错误 [英] Post Request working in Postman but returns Preflight error in Angular 2 app

查看:17
本文介绍了Post Request 在 Postman 中工作,但在 Angular 2 应用程序中返回 Preflight 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是来自浏览器控制台的错误日志XMLHttpRequest 无法加载 http://domain.com/xx/xxxxxxxx.预检响应具有无效的 HTTP 状态代码 404

THis is the error log from browser console XMLHttpRequest cannot load http://domain.com/xx/xxxxxxxx. Response for preflight has invalid HTTP status code 404

这是在 Postman 中收到的预期响应

This is the expected response as received in Postman

{
  "status": "success",
  "code": "E012",
  "message": "Contact sent"
}

这是来自Angular 2的请求

this is the request made from Angular 2

makeRequest(name, recipient) {
let body = JSON.stringify({
  "name": name,
  "recipient": recipient
});

let authToken = localStorage.getItem('token');
console.log(authToken);
let headers = new Headers({'Authorization': authToken , 'Content-Type': 'application/json'}); 
let options = new RequestOptions({headers: headers});
return this.http.post(url, body, options )
  .map(res => res.json());

}

这里是 Yii2 中的行为函数

Here is the behaviors function in Yii2

public function behaviors()
{
    $behaviors = parent::behaviors();

   // remove authentication filter
    $auth = $behaviors['authenticator'];
    unset($behaviors['authenticator']);

   // add CORS filter
    $behaviors['corsFilter'] = [
        'class' => Cors::className(),
        'cors' => [
            // restrict access to
            '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;
    // avoid authentication on CORS-pre-flight requests (HTTP OPTIONS method)
    $behaviors['authenticator']['except'] = ['options'];

   return $behaviors;
}

这是我的 UrlManager

Here is my UrlManager

   'urlManager' => [
        'enablePrettyUrl' => true,
        'enableStrictParsing' => true,
        'showScriptName' => false,
        'rules' => [
            'POST <version:[w-]+>/sms' => '<version>/sms/send',
            'POST <version:[w-]+>/users/verify' => '<version>/user/verify', 
            'POST <version:[w-]+>/bulk' => '<version>/routine/index',
            'POST <version:[w-]+>/contact' => '<version>/contact/index'],

推荐答案

在某些情况下,浏览器会自动执行 预检请求 在实际发送卷轴之前检查允许的方法或动词列表.您可以在浏览器的网络选项卡中看到这些内容.我猜在 Postman 中,您是直接发送 POST 请求,而预先发送的 OPTIONS 请求应该是失败的请求.

In certain cases a browser will automatically perform a preflight request to check the list of allowed methods or verbs before actually sending the reel one. You can see those within your browser's network tab. I guess in Postman you are directly sending the POST request while the pre-sent OPTIONS request should be the failing one.

Yii 有一个内置动作在 ActiveController 类下定义 响应此类请求.但是在您的情况下,您是直接扩展其父控制器,因此您需要在控制器中手动定义类似的操作 (或它们的父控制器) 以响应预检请求:

Yii has a built-in action which is defined under the ActiveController class to respond to such requests. But in your case you are directly extending its parent controller instead so you'll need to manually define a similar action inside your controllers (or a parent one to them) responding to preflight requests:

public function actionOptions() 
{
    if (Yii::$app->getRequest()->getMethod() !== 'OPTIONS') {
        Yii::$app->getResponse()->setStatusCode(405);
    }

    $allowed_verbs = ['GET', 'POST', 'HEAD', 'OPTIONS'];
    Yii::$app->getResponse()->getHeaders()->set('Allow', implode(', ', $allowed_verbs));
}

还有;因为您没有使用 内置的 REST 路由机制;在您的情况下,您还需要手动定义 rules 到该 Options 操作:(从您的评论中编辑的代码版本)

Also; as you are not using the built-in routing mechanism for REST; in your case you'll also need to manually define rules to that Options action: (edited version of the code from your comments)

'urlManager' => [ 
    'enablePrettyUrl' => true,
    'enableStrictParsing' => true,
    'showScriptName' => false,
    'rules' => [ 
        'POST <version:[w-]+>/users/verify' => '<version>/user/verify',
        'POST <version:[w-]+>/airtime' => '<version>/airtime/airtime',
        'POST <version:[w-]+>/bulk' => '<version>/routine/index',
        'POST <version:[w-]+>/contact' => '<version>/contact/index',

        // OPTTIONS URI ENDPOINTS
        'OPTIONS <version:[w-]+>/users/verify' => '<version>/user/options',
        'OPTIONS <version:[w-]+>/airtime' => '<version>/airtime/options',
        'OPTIONS <version:[w-]+>/bulk' => '<version>/routine/options',
        'OPTIONS <version:[w-]+>/contact' => '<version>/contact/options',
    ],
];

这篇关于Post Request 在 Postman 中工作,但在 Angular 2 应用程序中返回 Preflight 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆