首页 > 解决方案 > 来自 Heroku 托管的 Express 的“应用程序崩溃”和 503 错误响应

问题描述

在 Heroku 上托管我的 Node.js Express 服务器并尝试使用 Netlify 上托管的 React 应用程序连接到它时,我有时会遇到 CORS 错误。我在本地运行没有任何问题(即使前端和后端是不同的 URL)。

我越来越:

从源“ https://[frontend-netlify-url] ”访问“ https://[backend-heroku-url] ”处的 XMLHttpRequest已被 CORS 策略阻止:没有“Access-Control-Allow-Origin”标头存在于请求的资源上。

我正在使用默认情况下应该允许所有内容的“cors”npm 包。

应用程序.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=connect=服务=状态=503字节=协议=https

在我收到一个错误之后,客户端上到达后端的每个请求现在都会抛出一个 CORS 错误。我似乎可以让它重新开始工作的唯一方法是重新启动 Heroku 服务器,它会再次工作,直到它突然不再工作。

我不知道还能尝试什么。我已经把 cors() 东西扔到了整个地方,希望它会有所帮助(据我所知,我应该只需要在 app.js 中使用 app.use(cors()) 做一次)。我想我的下一步是尝试在 Heroku 之外的另一个服务上托管节点应用程序,看看它是否仍然做同样的事情,我真的不想这样做。

标签: node.jsexpressheroku

解决方案


在我的特殊情况下,这似乎是由@sideshowbarker 建议的完全与CORS 无关的错误引起的。

原来 fs.unlink() 是在下载实际完成之前运行的,所以在服务器完成读取之前文件就被删除了。我想这是一个竞争条件,这就是它如此不一致的原因。


推荐阅读