【问题标题】:Reactjs Preflight Request ErrReactjs 预检请求错误
【发布时间】:2020-07-07 15:51:43
【问题描述】:

我正在尝试使用基本身份验证ReactJSfetch 一个API(这是一个复杂的请求)。

我偶然发现了很多文章,大多数都建议在node 上修改一些内容,但在这里,在这种情况下,我没有使用任何节点服务器。我已经注释掉了所有NodeJS 代码,我直接从componentDidMount() 获取这个API,显然ReactJS 有它自己的后端服务器。我目前正在使用第三方 cors chrome 插件,但我反对使用第三方代理服务器,如 HerokuNGINX 或第三方库,如 axios。 Cors chrome 插件帮助我解决了access-control-allow-origin 问题,但随后又引发了这个新问题。

Access to fetch at 'https://server-iam-fetching/' 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.

我尝试了一些方法,例如在标题上附加访问控制检查,但似乎都没有。这是我的示例代码:

let headers = new Headers();
headers.append("Access-Control-Request-Headers", "*")

headers.append('Authorization','Basic ' + btoa(username + ":" + password));
    credentials
    allow requests
    allow origins
    ..
    ..
    etc
const someRequest = new Request(url, {
  method: 'GET',
  headers:headers,
  mode:'cors',
  cache: 'default'
});

componentDidMount(){
  fetch(someRequest)
    .then(response => response.json())
    .then(json => console.log(json))
}

如有任何问题,请随时发表评论。我在 MacOS 上。另外,我不想禁用我的 chrome 网络安全。

【问题讨论】:

  • @AmerllicA 我在 MacOS 上
  • 你有这个问题只是在开发模式下?生产模式和启动时运行是否存在 CORS 错误?
  • 是的,我处于开发模式,一旦我启动它就会看到这个问题。
  • 我会发布一个仅用于开发的答案,但这不是最终答案。如果它是有用的只是答案。
  • 删除headers.append("Access-Control-Request-Headers", "*")。它自己的那个不会使事情正常进行,但它是错误的,它没有帮助。您不能在 JavaScript 代码中手动设置该标头。浏览器控制该标题。

标签: javascript node.js reactjs security cors


【解决方案1】:

实际上,如果您可以访问 API,您应该在您的 NGINX 配置或后端代码上修复它。但如果您无法访问,则推荐两种方式:

  1. 通过 node/express 编写映射器代理 API,并将所有调用发送给它,映射器 API 将其发送到主 API。在您有权访问的映射器中允许所有来源:

    const express = require('express');
    const request = require('request');
    
    const app = express();
    
    app.use((req, res, next) => {
        res.header('Access-Control-Allow-Origin', '*');
        next();
    });
    
    app.get('/jokes/random', (req, res) => {
        request(
            { url: 'https://the-main-api-address' },
            (error, response, body) => {
                if (error || response.statusCode !== 200) {
                    return res.status(500).json({ type: 'error', message: err.message });
                }
    
                res.json(JSON.parse(body));
            }
        )
    });
    
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => console.log(`listening on ${PORT}`));
    
  2. 如果你使用webpack-dev-server,你可以使用下面的配置来允许你的 webpack devServer 上的所有来源:

    devServer: {
      ...
      headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
        "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
      }
    }
    

    或者传递一个proxy

        devServer: {
       contentBase: DIST_FOLDER,
       port: 8888,
       // Send API requests on localhost to API server get around CORS.
       proxy: {
          '/api': {
             target: {
                host: "0.0.0.0",
                protocol: 'http:',
                port: 8080
             },
             pathRewrite: {
                '^/api': ''
             }
          }
       }
    },
    

提示:我更喜欢使用第一个。

【讨论】:

  • 不幸的是,我的代码中没有使用任何express()nginx,它只是纯粹的reactjscomponentDidMount() 调用提取
  • @JumpMan,所以选择第二种方式,使用 webpack config 解决 CORS 问题。
【解决方案2】:

这篇文章只是为了你的开发模式,你可以启动一个没有安全模块的谷歌浏览器实例,它不会发送OPTION调用,你肯定不会看到CORS错误,所以打开你的终端并在其中写入以下命令:

open -n -a /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --user-data-dir="/tmp/chrome_dev_test" --disable-web-security

【讨论】:

  • 对不起,我没有更新这个问题,这对我没有帮助。
  • @JumpMan,我会为你的整个项目发布另一个答案。开发和生产。
  • @JumpMan,它是一些项目的解决方案,例如我的项目,这些项目仅在开发区域出现 CORS 错误,而生产 CORS 将消失。因此,如果可以删除问题帖子中新更新的句子。
猜你喜欢
  • 2023-04-03
  • 2015-08-10
  • 2020-10-26
  • 1970-01-01
  • 2022-11-03
  • 2019-04-11
  • 2017-05-06
  • 2021-08-25
  • 2019-10-03
相关资源
最近更新 更多