【问题标题】:Application always serves '/' to express app应用程序总是提供'/'来表示应用程序
【发布时间】:2019-08-01 00:53:01
【问题描述】:

有一个 Angular 7 应用程序并使用 node 和 express 实现了 Angular Universal,然后部署到 Firebase。

在尝试加载根 (/) 以外的页面时遇到问题,导致服务器返回根 (/) 的 html 而不是用户请求的页面。

不确定问题出在哪里(Angular、Angular Universal 或 Firebase)。

这是我的index.ts

import * as functions from 'firebase-functions';

import 'zone.js/dist/zone-node';
import 'reflect-metadata';

import {renderModuleFactory} from '@angular/platform-server';
import {enableProdMode} from '@angular/core';

import * as express from 'express';
import {readFileSync} from 'fs';

enableProdMode();

const app = express();

const indexHtml = readFileSync(__dirname + '/index-server.html', 'utf-8').toString();

const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./main');

import {provideModuleMap} from '@nguniversal/module-map-ngfactory-loader';

app.engine('html', (_, options, callback) => {
  // Always '/' (root path)
  console.log('OPTIONS.REQ.URL', options.req.url);

  renderModuleFactory(AppServerModuleNgFactory, {
    // My index-server.html
    document: indexHtml,
    url: options.req.url,
    extraProviders: [
      provideModuleMap(LAZY_MODULE_MAP)
    ]
  }).then(html => {
    callback(null, html);
  });
});

app.set('view engine', 'html');
app.set('views', __dirname);

app.get('*.*', express.static(__dirname + '/dist', {
  maxAge: '1y'
}));

app.get('*', (req, res) => {
  res.render(__dirname + '/index-server.html', {req});
});

exports.ssrApp = functions.https.onRequest(app);

这是我的app-routing.module.ts

import {RouterModule, Routes} from '@angular/router';
import {NgModule} from '@angular/core';
import {HomePageComponent} from './home-page/home-page.component';
import {ToursComponent} from './tours/tours.component';
import {MaltaComponent} from './malta/malta.component';
import {AboutComponent} from './about/about.component';
import {ContactComponent} from './contact/contact.component';
import {TourComponent} from './tours/tour/tour.component';
import {ErrorComponent} from './error/error.component';
import {BlogComponent} from './blog/blog.component';
import {BlogPageComponent} from './blog/blog-page/blog-page.component';
import {PageResolver} from './services/pages/page-resolver.service';

const AppRoutes: Routes = [
  {
    path: 'home',
    component: HomePageComponent,
    data: {
      state: 'home',
      pageId: 'home'
    },
    resolve: {
      page: PageResolver
    }
  },
  {
    path: 'tours',
    component: ToursComponent,
    data: {
      state: 'tours',
      pageId: 'tours'
    },
    resolve: {
      page: PageResolver
    }
  },
  {
    path: 'tours/:id',
    component: TourComponent,
    data: {
      state: 'tour'
    }
  },
  {
    path: 'blog',
    component: BlogComponent,
    data: {
      state: 'blogs',
      pageId: 'blog'
    },
    resolve: {
      page: PageResolver
    }
  },
  {
    path: 'blog/:id',
    component: BlogPageComponent,
    data: {
      state: 'blog'
    }
  },
  {
    path: 'malta',
    component: MaltaComponent,
    data: {
      state: 'malta',
      pageId: 'malta'
    },
    resolve: {
      page: PageResolver
    }
  },
  {
    path: 'about',
    component: AboutComponent,
    data: {
      state: 'about',
      pageId: 'about'
    },
    resolve: {
      page: PageResolver
    }
  },
  {
    path: 'contact',
    component: ContactComponent,
    data: {
      state: 'contact',
      pageId: 'contact'
    },
    resolve: {
      page: PageResolver
    }
  },
  {
    path: 'something-went-wrong',
    component: ErrorComponent,
    data: {
      state: 'error',
      pageId: 'error'
    }
  },
  {
    path: '',
    redirectTo: '/home',
    pathMatch: 'full'
  },
  {
    path: '**',
    redirectTo: '/something-went-wrong'
  }
];

@NgModule({
  imports: [
    RouterModule.forRoot(AppRoutes, {
      useHash: true,
      scrollPositionRestoration: 'enabled',
      initialNavigation: 'enabled'
    })
  ],
  exports: [RouterModule]
})

export class AppRoutingModule {

}

这是我的firebase.json

{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "function": "ssrApp"
      }
    ]
  },
  "functions": {
    "predeploy": "npm --prefix \"$RESOURCE_DIR\" run build"
  }
}

不胜感激任何有关此问题的帮助!

【问题讨论】:

    标签: node.js angular firebase express angular-universal


    【解决方案1】:

    您的问题与Browser URL styles有关

    基于此answer:尝试将重写从"function": "ssrApp" 更改为"destination": "/index-server.html"

    请求index-server.html会触发该函数。

    【讨论】:

    • 嗨耶,谢谢你的回答。我像你说的那样更改了重写,但是现在我收到 404 错误。 firebase.json 文件是我唯一需要做的改变吗?
    • 请阅读并尝试理解我提供的链接。它可以比我的回答更好地帮助你。
    • 谢谢yeya,是useHash: true 导致了这种行为。感谢您的帮助!
    【解决方案2】:

    app-routing.module.ts 中删除useHash: true 后问题得到解决。

    感谢 yeya 帮助我们找到解决方案。

    【讨论】:

    • 将其标记为正确答案。这样您的问题就不会留在“未回答”列表中
    • 一旦 Stackoverflow 允许我将其标记为正确,我会 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多