首页 > 解决方案 > 从 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'));
    });
}

标签: node.jsangularexpress

解决方案


推荐阅读