【发布时间】:2019-12-06 03:50:33
【问题描述】:
我正在使用“create-react-app”、express、cors 和 mysql 创建一个反应应用程序,用户应该在其中输入一些详细信息,然后将其发送到数据库。所有现有条目都应显示在 Web 应用程序上。 我在本地尝试过,一切正常。数据库已填充,并且请求已在 Web 应用程序上显示数据库条目。
然后我在“npm run build”命令后部署到我的网络主机(all-inkl.com)。现在,数据库条目没有显示,我也不能再填充数据库了。 Chrome DevTools 和 Safari Inspector 告诉我,它与 CORS 相关。经过一些研究,我知道,由于 CORS 政策(和 SOP 政策?),对 db 的请求应该来自同一个域。但我不知道如何解决它。 在this post 中,问题是不正确的数据库凭据。就我而言,我很确定凭据是正确的。
在这个代码块Chrome会抛出相应的错误
getBets = _ => {
fetch("http://www.subdomain.example.de/bets")
.then(response => response.json())
.then(response => this.setState({bets: response.data}))
.catch(err => console.error(err))
};
Chrome DevTools 错误:
加载资源失败:服务器响应状态为 404(未找到)
CORS 策略已阻止从源“http://www.subdomain.example.de/test”获取“http://www.subdomain.example.de/test”的访问权限:请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
TypeError: 获取失败
Safari 检查器错误:
Access-Control-Allow-Origin 不允许Origin http://subdomain.example.de。
由于访问控制检查,Fetch API 无法加载 http://www.subdomain.example.de/test。
加载资源失败:Access-Control-Allow-Origin 不允许 Origin http://subdomain.example.de
TypeError: Origin http://subdomain.example.de is not allowed by Access-Control-Allow-Origin
由于我不知道代码的哪一部分包含问题,所以整个代码如下。
server.js
const express = require("express");
const cors = require("cors");
const mysql = require("mysql");
const app = express(); //initialize express
// const PORT = process.env.port;
const SELECT_ALL_BETS_QUERY = "SELECT * FROM markers";
const connection = mysql.createConnection({
host: "http://www.subdomain.example.de",
user: "***",
password: "***",
database: "***"
});
connection.connect(err => {
if (err) {
return err;
}
});
app.use(cors());
app.get("/", (req, res) => {
res.send("go to /test to see tests")
});
app.get("/test", (req, res) => {
connection.query(SELECT_ALL_BETS_QUERY, (err, results) => {
if (err) {
return res.send(err)
}
else {
return res.json({
data: results
})
}
})
});
app.get("/test/add", (req, res) => {
const {name, test, count1, count2, type} = req.query;
const INSERT_BET = `INSERT INTO markers (name, test, lat, lng, type) VALUES("${name}", "${test}", 99, 88, "test3")`;
connection.query(INSERT_BET, (err, results) => {
if (err) {
return res.send(err);
}
else {
return res.send("succesfully added your test")
}
})
});
app.listen(4000, () => {
console.log("I'm listening to port 4000")
});
App.js
import React, { Component } from "react";
import './App.css';
class App extends Component {
state = {
tests: [],
test: {
person_name: "Peter Pan",
time: "10:17 Uhr"
}
};
componentDidMount() {
this.getTest();
}
getTests = _ => {
fetch("http://www.subdomain.example.de/test")
.then(response => response.json())
.then(response => this.setState({tests: response.data}))
.catch(err => console.error(err))
};
addTest = _ => {
const { test } = this.state;
fetch(`http://www.subdomain.example.de/tests/add?name=${test.person_name}&bet=${test.time}`)
.then(response => response.json())
.then(this.getTests)
.catch(err => console.error(err))
};
renderBets = ({ test_id, name, test}) =>
<div key={test_id}>
<p>{name}</p>
<p>{test}</p>
</div>;
render() {
const { tests, test } = this.state;
return (
<div>
{tests.map(this.renderTests)}
<div>
<input
value={test.person_name}
onChange={e => this.setState({test: { ...test, person_name: e.target.value}})}
/>
<input
value={test.time}
onChange={e => this.setState({test: { ...test, time: e.target.value}})}
/>
<button onClick={this.addTest}>Click Me</button>
</div>
</div>
)
}
}
export default App;
服务器边界条件信息
服务器由 all-inkl.com 托管。由于 ssh 的可能性,我使用高级帐户。使用 ssh 我在我的项目目录中安装了 node.js。 node.js 是必需的,因为我的项目是用 reactJS 构建的。 如果由于服务器配置有任何进一步的信息,请询问,因为我不知道哪些信息有帮助。 我按照说明在this page上安装node.js
此外,我在 .htaccess 文件中添加了以下内容:
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
编辑
我找到了一个有用的(希望是)网页test-cors。测试在不传递任何请求标头的情况下输出以下内容:
Fired XHR event: loadstart
Fired XHR event: readystatechange
Fired XHR event: progress
Fired XHR event: readystatechange
Fired XHR event: readystatechange
Fired XHR event: load
XHR status: 200
XHR status text:
XHR exposed response headers:
cache-control: public, max-age=600
content-encoding: gzip
content-type: text/html
date: Fri, 02 Aug 2019 17:36:12 GMT
etag: "1rO4KQ"
expires: Fri, 02 Aug 2019 17:46:12 GMT
server: Google Frontend
x-cloud-trace-context: 2c0391d5a5e09665df3f0b243e2b90a6;o=1
XHR 状态是否意味着 CORS 正在运行并且没有任何错误?
【问题讨论】:
-
CORS 问题几乎总是与服务器有关。我认为您应该修改您的问题以添加有关您如何托管服务器的其他信息。
-
乍一看,
cors()的使用对我来说似乎是合法的。客户端代码无关紧要,最好为 OPTIONS 请求提供响应标头。可能您的代码在某处失败,并且为 OPTIONS 返回非 200 状态。 -
加载资源失败:服务器响应状态为 404(未找到)
-
@sideshowbarker 所以,server.js 很可能无法正常工作,不是吗?在本地,我使用 nodemon 启动 server.js。在由 all-inkl.com 托管的服务器上,如果有必要,我根本不知道哪个命令启动 server.js。会不会是这个问题?
-
@technogeek1995 好的,那我就在正确的轨道上。关于 server.js 文件,我将再次与他们联系。非常感谢您的帮助。如果他们不能解决,我会更换提供者。