使用 React 调用 Front 中的 API 时出错
当我尝试单击按钮进行订阅时,出现了一个错误。这是浏览器控制台中的错误消息:
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'),
}),
]
};
我不确定这个错误来自哪里。我该如何修复它?
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,这可能不是您想要的。因此,任何网站都可以代表其访问者向您的网站发出请求并处理其响应。
这是因为您正在尝试调用在不同服务器中运行的服务。
如果用于开发环境,您应该使用某种代理,例如 webpack Dev 服务器 代理
另一种选择是通过某种插件禁用浏览器中的 cors 检查,在 chrome 应用商店中简单搜索就会为您提供许多插件。