【问题标题】:"You need to enable JavaScript to run this app." error when deploying React/Express app to heroku“您需要启用 JavaScript 才能运行此应用程序。”将 React/Express 应用程序部署到 heroku 时出错
【发布时间】:2020-04-02 16:16:01
【问题描述】:

我创建了一个基于 React 和 node/express 的应用程序,并尝试将其部署在 heroku 上。部署进展顺利,我的应用程序可在此处使用:https://sbansal-campaign-manager.herokuapp.com/

但是,即使请求返回 200 响应,调用后端 api 和加载数据也存在问题。

但是,当我单击“预览”选项卡时,它显示:You need to enable JavaScript to run this app. 这是不正确的。 JS 已启用。我可以访问本地计算机上的数据,但当我在 heroku 上部署应用程序时无法访问。在下面分享我的服务器配置:

const express = require("express");
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

// IMPORT MODELS
require('./models/Campaign');

const app = express();

mongoose.Promise = global.Promise;
mongoose.connect(
  process.env.MONGODB_URI ||
    `mongodb://<user>:<password>@ds145230.mlab.com:45230/sbansal-campaigns-db`
);

app.use(bodyParser.json());

//IMPORT ROUTES
require('./routes/CampaignRoutes')(app);

if (process.env.NODE_ENV === "production") {
  app.use(express.static("client/build"));

  const path = require("path");
  app.get("*", (req, res) => {
    res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
  });
}

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
  console.log(`app running on port ${PORT}`);
});

我是在 heroku 上部署东西的新手。请帮助解决问题。 这是完整的回购:https://github.com/saranshbansal/sbansal-campaign-manager

【问题讨论】:

  • sbansal-campaign-manager.herokuapp.com/api/campaigns 不是在输出广告系列列表,而是您网站的 HTML。
  • 是的,我知道,但它在开发机器上运行良好。可能是我可能必须允许来自所有主机的请求,但我找不到这样的设置。
  • 这可能是某种路由/服务器配置问题。你的 Github 中没有 Heroku Procfile 或 .htaccess,所以我不知道东西是如何路由到你的应用程序的。
  • @ceejayoz procfile 不再需要。 heroku 自动检查 package.json 中的启动脚本并生成它。

标签: node.js reactjs express heroku mongoose


【解决方案1】:

您需要在服务器端应用中启用 CORS。

如下所示,或创建您的自定义: // 设置 CORS

app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');

res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, 
Content-Type, Accept, Authorization');

if (req.method === 'OPTIONS') {

    res.header('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET');

    return res.status(200).json({});

}

next();

});

【讨论】:

  • CORS 无法解决 OP 的 API 服务于其 HTML 而不是 API 响应的事实。
【解决方案2】:

它在你的机器上工作的原因是因为你在定义:

if (process.env.NODE_ENV === "production") {
    ... 
}

当您部署到 Heroku 时,您正在部署主分支,它将在生产模式下运行。

这段代码清楚地表明你要返回所有路由的html页面:

  app.get("*", (req, res) => {
    res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
  });

【讨论】:

  • 我猜这不是问题。 youtu.be/eHWK4Pu6dmE 在所有教程中,这是在生产模式下编写的标准方式。
  • 也许本教程想要实现的目标与您不同。我只能对我看到的做出反应。只是暂时删除和部署没有生产的东西,看看会发生什么。从那里去。
  • 我已经这样做了,但并没有改变任何东西。本教程正在做我想做的事。
  • 你说它在你的本地机器上工作。你认为会有什么不同?我能看到的唯一明显区别是生产检查(由于上述答案中提到的原因,这是有道理的)。我在工作,不能看 youtube 视频 atm。您也没有在您调用的导入路由后面发布代码。您向我们展示的唯一内容是,如果模式是生产,则发回 html。那么你期待什么。
  • 当你说'已经做过'时,你到底做了什么?您是否删除了生产检查?您是否完全删除了通配符路由器?您是否添加了一些日志记录以查看在调用路由直到发回响应时会发生什么?我们愿意提供帮助,但您必须提供更多信息,而不是故意降低答案。
【解决方案3】:

最可能的原因是您的 index/server.js(节点应用程序文件)看起来像这样:

// DEV and PRODCTION HANDLER
if (process.env.NODE_ENV === 'DEV') {
    const morgan = require('morgan'),
    cors = require('cors')
    app.use(morgan('dev'),
    cors({ origin: `${process.env.HOST_IP}:${process.env.CLIENT_PORT}` })
   )
}

if (process.env.NODE_ENV === 'PROD') {
    const { resolve } = require('path')
    app.use(express.static(resolve(__dirname, '..', 'dist')))
    app.use('*', (req, res) => {
    res.sendFile(resolve(__dirname, '..', 'dist', 'index.html'))
    })
}

// WEB APP ROUTES
app.use('/api/', require('./api/Home.controller'))
app.use('/api/user/', require('./api/User.controller'))
app.use('/api/user/dashboard/', require('./api/Dashboard.controller'))
app.use('/api/chatbot', require('./api/Chatbot.controller'))
app.use('/api/transactions', require('./api/Transactions.controller'))

这是完全错误的,我也遇到了同样的错误,在做研究时我发现了这个问题,在此之后,我还找到了官方推荐的实际使用路线的方式,这清楚地表明应该是获取路线用它来服务反应文件。 这是文档的链接: https://create-react-app.dev/docs/deployment/#serving-apps-with-client-side-routing

这里发生的情况是,快递服务于来自 //DEV 和 PRODUCTION HANDLER 的响应。上面给出的代码有2个问题

  1. //DEV 和 PRODUCTION Handler 应该使用 app.get('') 而不是 app.use('') 来提供 react HTML 构建文件。
  2. res.sendFile 应该低于所有其他路由。

这也是 https://medium.com/@abdamin 的一篇非常好的博客,用于部署 MERN 应用程序:https://itnext.io/deploy-a-mongodb-expressjs-reactjs-nodejs-mern-stack-web-application-on-aws-ec2-2a0d8199a682

所以最后,正确的代码应该是这样的:

// DEV and PRODCTION HANDLER
if (process.env.NODE_ENV === 'DEV') {
    const morgan = require('morgan'),
    cors = require('cors')
    app.use(morgan('dev'),
    cors({ origin: `${process.env.HOST_IP}:${process.env.CLIENT_PORT}` })
   )
}

// WEB APP ROUTES
app.use('/api/', require('./api/Home.controller'))
app.use('/api/user/', require('./api/User.controller'))
app.use('/api/user/dashboard/', require('./api/Dashboard.controller'))
app.use('/api/chatbot', require('./api/Chatbot.controller'))
app.use('/api/transactions', require('./api/Transactions.controller'))

if (process.env.NODE_ENV === 'PROD') {
    const { resolve } = require('path')
    app.use(express.static(resolve(__dirname, '..', 'dist')))
    app.get('*', (req, res) => {
    res.sendFile(resolve(__dirname, '..', 'dist', 'index.html'))
    })
}

【讨论】:

    猜你喜欢
    • 2021-10-05
    • 2021-01-10
    • 2021-08-12
    • 2018-02-18
    • 2022-11-30
    • 1970-01-01
    • 2019-12-16
    • 2021-10-03
    • 2022-06-14
    相关资源
    最近更新 更多