javascript - 将 React 应用程序部署到生产环境返回“您需要启用 JavaScript 才能运行此应用程序”
问题描述
问题
我在“/artists”有一个 axios 调用,它获取作为 JSON 数组返回的艺术家列表。它在开发中工作。但是,在生产中,它会输出一个 HTML 元素,上面写着您需要启用 Javascript,因为从“/artists”返回的数据是未定义的(证明如下):
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="./favicon.ico" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
<link rel="apple-touch-icon" href="./logo192.png" />
<link rel="manifest" href="./manifest.json" />
<title>React App</title>
<link href="./static/css/main.5eece21d.chunk.css" rel="stylesheet" />
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script>
!(function (e) {
function t(t) {
for (var n, f, i = t[0], l = t[1], p = t[2], c = 0, s = []; c < i.length; c++) (f = i[c]), Object.prototype.hasOwnProperty.call(o, f) && o[f] && s.push(o[f][0]), (o[f] = 0);
for (n in l) Object.prototype.hasOwnProperty.call(l, n) && (e[n] = l[n]);
for (a && a(t); s.length; ) s.shift()();
return u.push.apply(u, p || []), r();
}
function r() {
for (var e, t = 0; t < u.length; t++) {
for (var r = u[t], n = !0, i = 1; i < r.length; i++) {
var l = r[i];
0 !== o[l] && (n = !1);
}
n && (u.splice(t--, 1), (e = f((f.s = r[0]))));
}
return e;
}
var n = {},
o = { 1: 0 },
u = [];
function f(t) {
if (n[t]) return n[t].exports;
var r = (n[t] = { i: t, l: !1, exports: {} });
return e[t].call(r.exports, r, r.exports, f), (r.l = !0), r.exports;
}
(f.m = e),
(f.c = n),
(f.d = function (e, t, r) {
f.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: r });
}),
(f.r = function (e) {
"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e, "__esModule", { value: !0 });
}),
(f.t = function (e, t) {
if ((1 & t && (e = f(e)), 8 & t)) return e;
if (4 & t && "object" == typeof e && e && e.__esModule) return e;
var r = Object.create(null);
if ((f.r(r), Object.defineProperty(r, "default", { enumerable: !0, value: e }), 2 & t && "string" != typeof e))
for (var n in e)
f.d(
r,
n,
function (t) {
return e[t];
}.bind(null, n)
);
return r;
}),
(f.n = function (e) {
var t =
e && e.__esModule
? function () {
return e.default;
}
: function () {
return e;
};
return f.d(t, "a", t), t;
}),
(f.o = function (e, t) {
return Object.prototype.hasOwnProperty.call(e, t);
}),
(f.p = "./");
var i = (this.webpackJsonpspotify = this.webpackJsonpspotify || []),
l = i.push.bind(i);
(i.push = t), (i = i.slice());
for (var p = 0; p < i.length; p++) t(i[p]);
var a = l;
r();
})([]);
</script>
<script src="./static/js/2.2cc1353a.chunk.js"></script>
<script src="./static/js/main.0515e6b9.chunk.js"></script>
</body>
出现此错误是因为在我的动作创建者中:
export const fetchArtists = () => async (dispatch: Dispatch) => {
const response = await axios.get<Artist[]>("/artists");
console.log(response);
dispatch<FetchArtistsAction>({
type: ActionTypes.FETCH_ARTISTS,
payload: response.data,
});
};
生产模式下的 console.log(response) 输出:
开发模式下的 console.log(response) 输出:
我的网站
https://spotify-eight.vercel.app/
该页面将加载,然后由于 /artists 路由调用,它会给您一个空白页面。它将你上面的生产输出,导致错误。
后端代码
我的 src/backend/artistRoutes.ts
router.get("/", async (req: RequestWithBody, res: Response) => {
const artists = await Artists.find({});
res.send(artists);
});
我的src/backend/index.ts,编译时生成src/backend/build:
.....
.....
mongoose.connect(process.env.mongoURI, { useNewUrlParser: true });
//Models
require("./models/Artists");
//Routes
app.use("/artists", artistsRoutes);
const PORT = process.env.PORT || 5000;
//Production
const path = require("path");
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "../../../build")));
app.get("*", function (req, res) {
res.sendFile(path.join(__dirname, "../../../build"));
});
}
app.listen(PORT);
我的项目的文件夹结构概述:
我已经在我的托管站点 Vercel中设置了我的生产环境变量:
我从其他帖子中尝试过的其他解决方案无济于事:
我在控制台中收到错误“您需要启用 JavaScript 才能运行此应用程序。” 反应
- 在 package.json 添加一个
"homepage": ".",
- 在 manifest.json 中,将起始 URL 更改
"start_url": ".",
为"start_url": "/",
- 添加代理服务器。自从我开始部署以来,我就已经启用了它。
"proxy": "http://localhost:5000"
解决方案
我假设您使用 nginx 或 apache 提供反应静态文件。
如果是这样,请尝试查看/etc/nginx/sites-enabled/the-config-file
,因为反应它通常有这一行:
try_files $uri /index.html;
它的作用是,如果有人访问https://spotify-eight.vercel.app/artists,尝试服务https://spotify-eight.vercel.app/artists/index.html,如果没有找到服务 rootPath/index。 html。我认为这就是正在发生的事情。
我建议在 :80 以外的另一个端口提供 api 端点,以便可以轻松区分静态文件和端点。不要更改 nginx 配置 try_files 指令,因为否则您的反应应用程序将无法正确提供路径。
推荐阅读
- graphql - Keystone 6上的GraphQL where子句中的错误
- python - asyncio 从财务 yahoo 下载选项报价
- rich-notifications - 如何获得丰富的 chrome 通知以在通知弹出时堆叠通知?
- javascript - 带有检测滚动的无限画廊
- python - 如何将列表作为参数传递给 ThreadPoolExecutor 并获取索引和值
- javascript - 用javascript激活php表单不起作用
- python - 列表和数据框的交集,保留列表的重复项,但显示数据框中列的值
- django - 用于测试的 django cookiecutter 媒体/位置
- python - 从相似类型中提取一个 url
- sql - 执行使用的 Postgresql 变量使用不返回结果