Angular Universal SSR使用导航器(窗口或其他仅浏览器的本机对象)

时间:2018-10-24 19:38:26

标签: angular angular-universal serverside-javascript ssr

从文档中

  

例如,您的服务器端页面无法引用仅浏览器的本机对象,例如窗口,文档,导航器或位置。如果不需要在服务器呈现的页面上使用它们,则可以使用条件逻辑来绕开它们。另外,您可以在所需的对象(例如位置或文档)上找到可注射的Angular抽象;它可能足以替代您正在调用的特定API。如果Angular不提供它,您可以编写自己的抽象,该抽象在浏览器中委派给浏览器API,并在服务器上委派给令人满意的替代实现。

服务器无法访问浏览器对象很有意义。但是可以实现:

  

或者,您可以在所需的对象(例如位置或文档)上找到可注射的Angular抽象;它可能足以替代您正在调用的特定API。

下一步:

  

如果Angular不提供它,您可以编写自己的抽象,该抽象在浏览器中委派给浏览器API,并在服务器上委派给令人满意的替代实现。

我在哪里可以找到Angular提供的内容以及如何使用它们?我正在寻找导航器。

如果Angular不提供导航器,我该如何编写自己的抽象?

侧节点:我使用ng add @nguniversal/express-engine --clientProject angular.io-example来开始使用ssr。

1 个答案:

答案 0 :(得分:0)

虽然我不推荐这种方法,但是如果您在Angular Universal中需要navigator对象,则可能要检查Domino项目。

然后,在您的server.ts文件中,您将执行以下操作:

const template = readFileSync(join(DIST_FOLDER, 'index.html')).toString();
const win = domino.createWindow(template);

global['window'] = win;
global['Node'] = win.Node;
global['navigator'] = win.navigator;
global['Event'] = win.Event;
global['Event']['prototype'] = win.Event.prototype;
global['document'] = win.document;

在处理程序中,您可以执行以下操作:

app.engine('html', (_, options, callback) => {
  renderModuleFactory(AppServerModuleNgFactory, {
    // Our index.html
    document: template,
    url: options.req.url,
    // DI so that we can get lazy-loading to work differently (since we need it to just instantly render it)
    extraProviders: [
      provideModuleMap(LAZY_MODULE_MAP)
    ]
  }).then(html => {
    callback(null, html);
  });
});

请参阅:https://mdbootstrap.com/angular/angular-universal/