开发者问题收集

使用 React 调用 Front 中的 API 时出错

2019-12-17
246

当我尝试单击按钮进行订阅时,出现了一个错误。这是浏览器控制台中的错误消息:

Access to fetch at ' https://api.exhia.com/api/accounts/addaccount ' from origin ' http://localhost:3000 ' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

这是处理点击的代码示例:

 handleFormSubmit(event) {
    event.preventDefault();
    this.setState({ msg: 'checked' });
    const validation = this.validator.validate(this.state);
    this.setState({ validation });
    this.submitted = true;
    if (
      this.state.checked === true &&
      validation.subConfirm_pwd.isInvalid === false
    ) {
      fetch(`${API}/api/accounts/addaccount`, {
        method: 'POST', // 'GET', 'PUT', 'DELETE'
        body: JSON.stringify({
          email: this.state.sub_mail,
          password: this.state.sub_pwd,
          acceptCGU: this.state.checked,
        }),
        headers: {
          'Content-Type': 'application/json;charset=utf-8',
          Accept: 'application/json',
        },
      })
        .then(res => res.json())

.....

我正在处理这个问题,这是我的 webpack.config:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
var OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'build'),
        publicPath: '/',
        filename: 'bundle.js'
    },
    devServer: {
        contentBase: path.join(__dirname, './build'),
        compress: true,
        port: 3000,
        historyApiFallback: true,
    },
    performance: {
        hints: false,
        maxEntrypointSize: 512000,
        maxAssetSize: 512000
    },
    module: {
      rules: [
        {
          test: /\.(css|sass|scss)$/,
          use: [
            MiniCssExtractPlugin.loader,
            {
              loader: 'css-loader',
              options: {
                sourceMap: true,
                importLoaders: 2
              },
            },
            {
              loader: 'sass-loader',
              options: {
                sourceMap: true,
              },
            },
          ],
        },
        {
          test: /\.(js|jsx)$/,
          exclude: /node_modules/,
          use: {
            loader: "babel-loader"
          }
        },
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: ["file-loader"]
        },
        {
            test: /\.(woff(2)?|ttf|otf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
            use: [
              {
                loader: 'file-loader',
                options: {
                  name: '[name].[ext]',
                  outputPath: 'fonts/'
                }
              }
            ]
        }
      ]
    },
     //remove comments from JS files
    optimization: {
        minimizer: [
        new UglifyJsPlugin({
            uglifyOptions: {
            output: {
                comments: false,
            },
            },
        }),
        new OptimizeCSSAssetsPlugin({
            cssProcessorPluginOptions: {
            preset: ['default', { discardComments: { removeAll: true } }],
            }
        })
        ],
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "[name].css"
        }),
        new ManifestPlugin(),
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: path.resolve('./public/index.html'),
        }),
    ]
};

我不确定这个错误来自哪里。我该如何修复它?

2个回答

http://localhost:3000 已被 CORS 策略阻止,因此您需要做的就是向为您的 API 提供服务的服务器添加 HTTP 标头。这意味着更改 API。

在您的情况下,这是 (fatboar.extia.com) 或 (api.exhia.com) - 我无法分辨哪一个,因为您似乎在您的问题/评论中互换使用它们。

此网站提供了有关如何执行此操作的详细信息: https://enable-cors.org/server.html - 如果您需要进一步的指导,我会研究如何为您的特定平台添加标头。您应该能够在 Postman 等工具中看到返回的标头( https://www.getpostman.com/ ) - 我会先使用该 API 探索标头,然后在浏览器中继续执行代码。

1) Access-Control-Allow-Origin: http://localhost:3000

注意。当您转到生产环境时,您可能需要更改上述内容以匹配进行调用的服务器。例如,目前您在 localhost:3000 上托管应用程序。当您转到生产环境时(假设您在 blah.com 上托管),您的访问控制标头也需要更改。

2) Access-Control-Allow-Origin: http://blah.com

不要被建议使用通配符的答案所诱惑,例如

3) Access-Control-Allow-Origin: * 

这将允许任何授权人员从任何域访问 API,这可能不是您想要的。因此,任何网站都可以代表其访问者向您的网站发出请求并处理其响应。

Squiggs.
2019-12-18

这是因为您正在尝试调用在不同服务器中运行的服务。

有关 cors 问题的更多信息

如果用于开发环境,您应该使用某种代理,例如 webpack Dev 服务器 代理

另一种选择是通过某种插件禁用浏览器中的 cors 检查,在 chrome 应用商店中简单搜索就会为您提供许多插件。

Nirjhar K. Paul
2019-12-17