node.js - 从 NodeJS Express 提供 Angular 子页面
问题描述
我有一个 Angular 应用程序,我正在对 dist 文件夹进行生产构建。它由 Express 服务器提供服务。我遇到的最大问题是 Angular 应用程序的子页面。我已经看到了关于 SO 的建议并且取得了有限的成功。就像现在一样,如果我刷新页面,浏览器 URL 保持不变,但它会转到 index.html 条目。
如果用户去其中之一
https://localhost/
https://localhost/cost-recovery
https://localhost/cost-recovery/finance
它转到 index.html 并被视为应用程序的入口点。
一个子网址是
https://localhost/cost-recovery/cost-dashboard
如果用户通过应用程序中的链接进行导航,则路由会正常工作并且页面会正确呈现。
在所有情况下,如果有人重新加载页面,应用程序会返回到入口页面,并且浏览器上的 URL 不会更改。
我很难将我的代码配对,因为并非我的所有路线都是通往 Angular 应用程序的路线。此外,Angular 应用程序需要经过身份验证。尽管如此,我想我已经设法只展示了基于 Angular 的片段。我意识到我展示的代码可以改进,但是我对同时具有 app.use 的东西、express.static(some path) 和 app.get('/', function( req,res) { res.sendFile("静态 Angular dist index.html 文件")}
在我的 index.html 中(我将 <base href 从 /cost-recovery 更改为 /:
<!DOCTYPE html>
<html lang="en">
<head>
<base href="/">
<oldbase href="/cost-recovery/"> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SPRINT Cost</title>
<link rel="icon" type="image/x-icon" href="./assets/ibm_icon.ico" />
<link rel="stylesheet" href="./assets/css/w3ds-5.4.0.css" />
<link rel="stylesheet" href="styles.3ff695c00d717f2d2a11.css"></head>
<body>
<app-root></app-root>
<script src="./assets/js/w3ds-5-4-0.js"></script>
<script type="text/javascript" src="runtime.06daa30a2963fa413676.js"></script><script type="text/javascript" src="polyfills.eda2d610c377a19f9f35.js"></script><script type="text/javascript" src="scripts.cc2b720567c4dabe68e6.js"></script><script type="text/javascript" src="main.d29d2f9ec5e70ab89fcd.js"></script></body>
</html>
路线片段:
var express = require('express');
var path = require('path');
const bodyParser = require('body-parser');
const FormData = require('form-data');
const axios = require('axios');
const fs = require('fs');
function getFullyLoadedApp() {
app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// app.use(express.static(path.join(__dirname, 'public')));
var cookieParser = require('cookie-parser');
app.use(cookieParser());
app.use(session({ resave: 'true', saveUninitialized: 'true', secret: config.secret }));
addRoutes(app, config);
return app;
}
function addRoutes(app, config) {
app.use(function (req, res, next) {
if (req.path == '/' || req.path.includes('download') || req.path.includes('static')) {
logger.info(req.path);
}
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-Width, Content-Type, Accept")
next();
});
app.use('/', express.static(__dirname + '/../client/dist'));
app.get('/', ensureAuthenticated, function (req, res) {
logger.info('Sending file ' + path.join(__dirname, '/../client/dist/client/index.html'));
res.sendFile(path.join(__dirname, '/../client/dist/client/index.html'));
});
app.use(express.static(__dirname + "/../client/dist/client"));
app.use('/sprint-cost-recovery*', ensureAuthenticated, function (req, res) {
/**
* Use normalize-url package to normalize the URL, ie. strip out excess /'s, make the
* ending URL. However, it insists on having a full HTTP url, including protocol, hostname
* etc. So this fakes it with a dummy URL.
*/
const dummy_host = 'https://dummyhost:8080';
var dummy_url = dummy_host + req.originalUrl;
const normalizeUrl = require('normalize-url');
var normalizedUrl = normalizeUrl(dummy_url);
normalizedUrl = normalizedUrl.substr(dummy_host.length);
newUrl = normalizedUrl.replace(/^\/sprint-cost-recovery/, '');
if (newUrl.endsWith('/') || newUrl === '') {
newUrl += '/index.html';
}
logger.info('Sending file ' + path.join(__dirname, '/../client/dist/client/index.html'));
res.sendFile(path.join(__dirname, '/../client/dist/client/index.html'));
});
}
解决方案
推荐阅读
- ssh - vscode 远程支持双 ssh 吗?
- openssl - VS 2017 未解析的外部符号 __imp__stricmp (libcrypto_static.lib)
- regex - 需要识别文件名中的特殊字符
- android - pubspec.yaml:解析块映射时需要一个键
- bash - 打印文件数据
- html - 与其他元素分组后更改元素属性
- php - 表中的 Laravel 日期格式
- javascript - Javascript条件可以在数字之间吗?
- r - 强制 ggplot2 包含一个具有 0 点的集群/组,以保持两个图之间的组数一致
- python - 在 Python 中压缩文件后如何检查数据损坏?