【问题标题】:POST request returns 401 during cross origin preflightPOST 请求在跨域预检期间返回 401
【发布时间】:2020-03-19 10:30:42
【问题描述】:

我一直在寻找一个看似非常基本的问题的答案。我正在尝试在 React 框架中使用 Axios 在本地主机上发出跨源 HTTP 请求。服务器端在 CodeIgniter 框架上运行,并使用 chriskacerguis 的 codeigniter-restserver。我已经配置了一个 .htaccess 文件来将 Access-Control-Allow-Origin 设置为 '*'。

我的 GET 请求正常工作。当我尝试发出 POST 请求时出现问题。我尝试过同时使用 fetch() 和 Axios。我在 Chrome 的控制台中收到此错误消息:

OPTIONS http://localhost/api/login 401 (Unauthorized)
(...)
localhost/:1 Access to XMLHttpRequest at 'http://localhost/api/login' from origin
'http://localhost:3000' has been blocked by CORS policy: Response to preflight request
doesn't pass access control check: It does not have HTTP ok status.

我相信服务器端代码可以正常工作,因为我能够使用 Insomnia 成功发出 POST 请求。虽然我在许多论坛上读到 401 错误与 CORS 问题无关,但在我看来它必须与 CORS 相关,因为我的 HTTP 请求在 Insomnia 中有效。

经过多次尝试更改标头和不同的配置选项,这是我在客户端的代码:

axios.post(api_url+'login', {
        headers: {
            'accept': 'application/json',
            'content-type': 'application/json',
        },
        data: {
            email: this.state.email,
            password: this.state.password
        },
        crossDomain: true,
        withCredentials: true,
        auth: {
            username: 'admin',
            password: '1234'
        }
    })
    .then(res => {
        console.log(res);
    })
    .catch(err => {
        console.log(err);
    });
}

在我看来,401 似乎是在初始 OPTIONS 请求中返回的。我不明白为什么会发生这种情况,因为我已经明白 OPTIONS 请求不应该需要身份验证。我也能够毫无问题地完成 Insomnia 中的 OPTIONS 请求。

这是我第一次尝试同时构建 REST API 和 React 应用程序。我花了很多时间试图使这个基本请求工作,我得出的结论是,我一定有一些非常明显的东西我遗漏了......非常感谢您的阅读和评论。

【问题讨论】:

  • 对您的服务的 HTTP OPTIONS 调用返回的错误代码是什么?应该在“正常状态”范围内(200 或 204)
  • 您是否在您的 codeigniter 服务器上启用了 cors 选项? stackoverflow.com/questions/25702991/…

标签: reactjs rest codeigniter http axios


【解决方案1】:

飞行前请求实际上做了以下事情:

CORS 预检请求是一个 CORS 请求,用于检查是否 理解 CORS 协议并且服务器知道使用特定的 方法和标头。

来源:https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request

在您的情况下,这与身份验证无关,但与从服务器收到的以下标头有关:

Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: *

如果OPTIONS 不在Allow-Methods 中,您将收到错误消息,如果您的前端主机和端口不在Allow-Origin 标头中,您也会收到错误消息。对于开发,可以将 Allow-Origin 设置为通配符 (*),但不要在生产环境中这样做。

要在 codeignter 中启用 CORS,您必须修改您的 rest.php,如下所示:

//Change this to TRUE
$config['check_cors'] = TRUE;

//No change here
$config['allowed_cors_headers'] = [
  'Origin',
  'X-Requested-With',
  'Content-Type',
  'Accept',
  'Access-Control-Request-Method'
];

//No change here
$config['allowed_cors_methods'] = [
  'GET',
  'POST',
  'OPTIONS',
  'PUT',
  'PATCH',
  'DELETE'
];

//Set to TRUE to enable Cross-Origin Resource Sharing (CORS) from any source domain
$config['allow_any_cors_domain'] = TRUE;


//Used if $config['check_cors'] is set to TRUE and $config['allow_any_cors_domain'] is set to FALSE. 
//Set all the allowable domains within the array
//e.g. $config['allowed_origins'] =['http://www.example.com','https://spa.example.com']

$config['allowed_cors_origins'] = [];

来源:https://stackoverflow.com/a/41206621/4934937

【讨论】:

  • 我不敢相信我之前没有在您的来源中看到答案。就是这样!只需要在 CodeIgniter 中处理 JSON 输入,它现在就可以完美运行了。感谢您的快速回答!
【解决方案2】:

将 OPTIONS 添加到允许的方法和以下“如果”对我有用:

header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if ( "OPTIONS" === $_SERVER['REQUEST_METHOD'] ) {
    die();
}

完整答案::https://stackoverflow.com/a/25703960/6052406

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-30
    • 2018-12-31
    • 2023-03-30
    • 2022-01-05
    • 2022-01-11
    • 2021-03-12
    • 2013-10-24
    • 2019-02-02
    相关资源
    最近更新 更多