使用 React 在 Front 调用 API 时出错
Posted
技术标签:
【中文标题】使用 React 在 Front 调用 API 时出错【英文标题】:Error when calling API in Front using React 【发布时间】:2020-04-10 06:01:31 【问题描述】:当我尝试单击按钮进行订阅时显示错误。这是浏览器控制台中的错误消息:
从源“http://localhost:3000”获取“https://api.exhia.com/api/accounts/addaccount”的访问权限已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头出现在请求的资源上。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
这是处理点击的代码示例:
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'),
),
]
;
我不确定错误来自哪里。我该如何解决?
【问题讨论】:
可能重复:***.com/questions/20035101/… - 本质上您正在执行跨域请求,因此如果远程服务器在您的控制之下,您必须代理或更改远程服务器。 你好 Squiggs,谢谢你的回答。请问我怎么能用代理来处理呢?因为我是服务器的管理员,但我不知道如何按照你说的那样更改远程 对于站点 B 想让站点 A 访问的每个资源/页面,站点 B 应该为其页面提供响应标头: Access-Control-Allow-Origin: siteA.com 所以,在你的在这种情况下,您将需要一个允许您在开发时使用本地主机的标头。 siteA 和 siteB 是什么意思?我只有一个站点:fatboar.extia.com :/ 您不要将该代码放在客户端或代码中的任何位置。它必须存在于您正在与之交谈的 API 中的服务器端。您提到您是“服务器管理员”——我认为这意味着您可以访问 API 的源代码。换句话说:api.exhia.com/api/accounts/addaccount 需要改变 【参考方案1】:http://localhost:3000 已被 CORS 策略阻止,因此您只需将 HTTP 标头添加到为您的 API 提供服务的服务器即可。这意味着更改 API。
在您的情况下,这是 (fatboar.extia.com) 或 (api.exhia.com) - 我不知道是哪一个,因为您似乎在您的问题/cmets 中可以互换使用它们。
此站点提供了有关如何执行此操作的详细信息:https://enable-cors.org/server.html - 如果您需要进一步的指导,我将研究如何为您的特定平台添加标题。您应该能够在 Postman (https://www.getpostman.com/) 之类的工具中看到返回的标头 - 我将首先探索 API 以检查标头,然后在浏览器中继续执行您的代码。
1) Access-Control-Allow-Origin: http://localhost:3000
注意。当您转移到生产环境时,您可能需要更改上述内容以匹配进行调用的服务器。因此,例如,当您在本地主机上托管应用程序时本地:3000。假设您在 blah.com 上托管,则当您转移到生产环境时,您的访问控制标头也需要更改。
2) Access-Control-Allow-Origin: http://blah.com
不要被暗示通配符的答案所诱惑,例如
3) Access-Control-Allow-Origin: *
这将允许任何授权人员从任何域访问 API,这可能不是您想要的。因此,任何站点都可以代表其访问者向您的站点发出请求并处理其响应。
【讨论】:
【参考方案2】:这是因为您正在尝试调用在不同服务器上运行的服务。
More on cors issue
如果是开发环境,你应该使用某种代理,例如 webpack Dev server proxy
另一种选择是通过某种插件禁用浏览器中的cors签入,在chrome应用商店中简单搜索会给你很多插件。
【讨论】:
你好 Squiggs,谢谢你的回答。它在 prod 而不是 dev 上,请查看上面 Edit 中的 webpack.config 你说我需要禁用浏览器中的 cors 检查,但每个人都不会这样做:/ 禁用 cors 和代理是我们通常在开发环境中所做的事情。在生产环境中,API 服务器应该允许主机配置或所有应用程序应该托管在同一个域中,我建议请参阅 cors 文档这里是一个很好的解释***.com/questions/36958999/… 嘿 Nirjhar,不幸的是它并没有真正帮助我解决我的问题,它只是解释了交叉的概念..以上是关于使用 React 在 Front 调用 API 时出错的主要内容,如果未能解决你的问题,请参考以下文章
调用 AWS API Gateway Private 无法从 Front 访问,但 EC2 有效