使用 Angular Universal 进行服务器端渲染避免 window is not defined 的错误消息

举报
Jerry Wang 发表于 2023/02/25 15:40:34 2023/02/25
【摘要】 尽管 Universal 项目的目标是能够在服务器上无缝呈现 Angular 应用程序,但开发人员还是应该考虑一些注意事项。首先,服务器和浏览器环境之间存在明显差异。 在服务器上呈现时,您的应用程序处于 ephemeral 或者 Snapshot 状态。应用程序完全呈现一次,返回生成的 HTML,其余应用程序状态在下一次呈现之前被销毁。其次,服务器环境本质上不具有与浏览器相同的功能(并且具有...

尽管 Universal 项目的目标是能够在服务器上无缝呈现 Angular 应用程序,但开发人员还是应该考虑一些注意事项。

首先,服务器和浏览器环境之间存在明显差异。 在服务器上呈现时,您的应用程序处于 ephemeral 或者 Snapshot 状态。

应用程序完全呈现一次,返回生成的 HTML,其余应用程序状态在下一次呈现之前被销毁。

其次,服务器环境本质上不具有与浏览器相同的功能(并且具有一些浏览器同样不具有的功能)。 例如,服务器没有任何cookies 的概念。

固然开发人员可以 polyfill 来一定程度上规避这个问题,但是没有完美的解决方案。

另请注意 SSR 的目标:改进应用程序的初始渲染时间。 这意味着应避免或充分防范任何可能降低此初始渲染中应用程序速度的情况出现。

一些 启用 SSR 后的常见错误:

window is not defined

使用 Angular Universal 时最常见的问题之一是服务器环境中缺少浏览器全局变量。 这是因为 Universal 项目使用 domino 作为服务器 DOM 呈现引擎。 因此,服务器上不会存在或不支持某些功能。 这包括窗口和文档全局对象、cookie、某些 HTML 元素(如画布)和其他几个。 Domino 代表节点中的 DOM.

在这里插入图片描述

解决这个错误的一些思路:

通常,需要的全局变量可以通过 Angular 平台通过依赖注入 (DI) 获得。 例如,全局文档可通过 DOCUMENT 令牌获得。 此外,通过 DOCUMENT 对象可以获得 window 和 location 的非常原始的版本。 例如:

示例代码如下:

import { Injectable, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

@Injectable()
export class ExampleService {
  constructor(@Inject(DOCUMENT) private _doc: Document) {}

  getWindow(): Window | null {
    return this._doc.defaultView;
  }

  getLocation(): Location {
    return this._doc.location;
  }

  createElement(tag: string): HTMLElement {
    return this._doc.createElement(tag);
  }
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。