【发布时间】:2019-11-05 07:41:58
【问题描述】:
当我在 Heroku 上托管我的 Node.js Express 服务器并尝试使用 Netlify 上托管的 React 应用程序连接到它时,我遇到了 CORS 错误有时。我在本地运行没有任何问题(即使前端和后端是不同的 URL)。
我明白了:
从源“https://[frontend-netlify-url]”访问“https://[backend-heroku-url]”处的 XMLHttpRequest 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头。
我正在使用'cors' npm 包,默认情况下应该允许所有内容。
app.js
const express = require("express");
const cors = require("cors");
const trackRoutes = require("./routes/trackRoutes");
const app = express();
app.use(cors());
app.use("/tracks", trackRoutes);
const port = process.env.PORT || 4000;
const server = app.listen(port, () => {});
trackRoutes.js
const express = require("express");
const router = express.Router();
const cors = require("cors");
router.all("*", cors());
const controller = require("../controllers/tracks");
router.get("/", cors(), controller.getTracks);
router.get("/download", cors(), controller.downloadTrack);
module.exports = router;
trackController.js
const { Track } = require("../db/db");
exports.getTracks = async (req, res, next) => {
const results = await Track.findAll({ raw: true });
res.status(201).json(results);
};
exports.downloadTrack = async (req, res) => {
const id = req.query.id;
const filePath = path.join(global.tempPath, id + ".mp3");
blob.getBlobToLocalFile("tracks", id, filePath, err => {
if (err) throw err;
try {
res.download(filePath, () => {
fs.unlink(filePath);
});
} catch (error) {
fs.unlink(filePath);
}
});
};
在客户端(React 应用)
<a href='https://[backend-heroku-url]/tracks/download?id=123'>
在客户端,我只是使用链接来点击 downloadTrack 路由,有时会运行并下载文件。其他时候它会抛出 CORS 错误。
因此,Heroku 日志中包含以下内容:
at=error code=H10 desc="App crashed" method=GET path="/tracks/download?id=7b4013b0-9550-11e9-a752-9561bb97f681" request_id=fc3945e8-af23-4c05-a432-03601ba199b5 dyno =连接=服务=状态=503字节=协议=https
在我收到一个错误后,客户端上到达后端的每个请求现在都会引发 CORS 错误。我似乎让它重新开始工作的唯一方法是重新启动 Heroku 服务器,它会再次工作,直到它突然不再工作。
我不知道还能尝试什么。我已经把 cors() 东西扔到了整个地方,希望它会有所帮助(据我所知,我应该只用 app.js 中的 app.use(cors()) 做一次)。我想我的下一步是尝试在 Heroku 之外的另一个服务上托管节点应用程序,看看它是否仍然做同样的事情,我真的不想这样做。
【问题讨论】:
-
收到该错误消息时响应的 HTTP 状态代码是什么?您可以使用网络窗格浏览器 devtools 进行检查。是 503 还是其他 5xx 错误,而不是 200 OK 成功响应?日志中显示的 App crashed 消息,以及您需要重新启动 Heroku 服务器才能再次获得成功响应的事实——这些表明您遇到的实际问题是您的 Heroku 应用程序在您尝试向其发送请求时已停止,因此返回的响应是 5xx 错误。
-
您看到 CORS 消息的唯一原因是 5xx 错误响应永远不会包含 Access-Control-Allow-Origin 响应标头。考虑以下情况:您的应用程序已崩溃,因此您的应用程序设置的响应标头不会添加到响应中。所以你需要解决的真正问题是找出导致你的应用程序崩溃的原因。原因与您的 CORS 配置完全无关。
-
这是一个很好的观点。我不认为它与 CORS 无关,但浏览器只是抱怨 CORS,因为它没有包含在响应中,因为一个不相关的错误......