使用 Angular 服务器端渲染 Transfer State Service

作者:??JerryWang_sap???? 时间:2024-04-22 22:39:50 

假设我们使用 Angular Universal 开发一个服务器端渲染的 Angular 应用,这个应用会消费一个第三方的 Restful API.

上述场景分为下列六个步骤:

  • 用户向部署了 Angular 服务器端应用的 Node.js 服务器发起页面请求

  • Node.js 调用第三方 Restful API,

  • 第三方 Restful API 返回结果,这个结果被用于渲染最后的页面

  • 服务器端渲染的页面,返回给浏览器

  • Angular 在浏览器中引导,并再次调用 Restful API

  • Restful API 返回给浏览器,Angular 客户端应用重新将数据渲染到视图中。

使用 Angular 服务器端渲染 Transfer State Service

我们可以通过创建 TransferState 服务来提高应用程序的效率,该服务是在 Node.js 服务器和浏览器中呈现的应用程序之间交换的一个键值注册表。

我们将通过一个 HTTP_INTERCEPTOR 机制来使用它,该机制将驻留在 HttpClient 服务中,并将操纵请求和响应。

创建一个新的 class,实现 HttpInterceptor 接口定义的 intercept 方法:

@Injectable({
providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor
public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>

每当对 HttpClient 服务执行任何 API 调用时,都会调用此方法。

为了简单起见,我们仅针对 GET 方法启用 TransferState:

if (request.method !== 'GET') {
    return next.handle(request);
  }

我们根据 GET 请求的 URL 生成一个密钥。 我们将使用键值对来存储或检索请求响应,具体取决于请求是在服务器端还是浏览器端处理:

const key: StateKey<string> = makeStateKey<string>(request.url);

为了区分服务器和浏览器运行环境,我们使用@angular/common库中的 isPlatformServer 方法以及 PLATFORM_ID 注入令牌:

if (isPlatformServer(this.platformId)) {
      //serverSide
  } else {
      //browserSide
  }

当服务器端渲染时,我们将 API 结果写入 Transfer State 注册表中:

if (isPlatformServer(this.platformId)) {
   return next.handle(request).pipe(tap((event) => {
     this.transferState.set(key, (<HttpResponse<any>> event).body);
   }));

在浏览器端代码中,我们要检查给定 HTTP 请求的响应是否已经驻留在 Transfer State 注册表中。 如果存在,我们直接从注册表中取出值,并清除注册表,以便将来的调用可以存储新数据,并将响应返回给调用者。

当且仅当注册表中不存在给定的键,我们才在客户端环境下执行 HTTP 调用。

else {
   const storedResponse = this.transferState.get<any>(key, null);
   if (storedResponse) {
     const response = new HttpResponse({body: storedResponse, status: 200});
     this.transferState.remove(key);
     return of(response);
   } else {
     return next.handle(request);
   }
 }

来源:https://juejin.cn/post/7112718815292571656

标签:Angular,渲染,Transfer,State,Service
0
投稿

猜你喜欢

  • python关键字传递参数实例分析

    2023-08-24 04:28:34
  • python中读入二维csv格式的表格方法详解(以元组/列表形式表示)

    2023-04-19 06:39:39
  • MYSQL 数据库同步

    2008-11-24 12:39:00
  • 举例讲解Python面向对象编程中类的继承

    2022-02-09 02:59:14
  • 如何远程连接SQL Server数据库的图文教程

    2024-01-12 15:32:32
  • MySQL连接时出现2003错误的实现

    2024-01-22 17:17:30
  • javascript 移动鼠标得到单元格所在table表中的rowIndex位置[兼容ie,firefox] <font color=red>原创</font>

    2024-04-18 09:50:31
  • TOPI如何使TVM代码不那么样板化

    2022-02-02 00:22:07
  • MySQL (root@%) does not exist的问题

    2011-03-16 15:31:00
  • 基于Tensorflow的MNIST手写数字识别分类

    2023-12-01 11:35:18
  • Pandas数据离散化原理及实例解析

    2022-06-26 21:45:14
  • JS实现给对象动态添加属性的方法

    2024-04-22 13:07:07
  • 用python求一个数组的和与平均值的实现方法

    2021-01-10 20:11:24
  • 使用Oracle的Decode函数进行多值判断

    2024-01-28 09:12:54
  • Mysql数据库之Binlog日志使用总结(必看篇)

    2024-01-20 20:15:16
  • 详解Django 时间与时区设置问题

    2021-02-19 03:08:42
  • 深入分析javascript中console命令

    2024-06-05 09:34:26
  • Python合并Excel表(多sheet)的实现

    2023-08-06 21:59:11
  • Pytest测试报告工具Allure的高级用法

    2023-06-20 17:21:09
  • pygame实现俄罗斯方块游戏(基础篇3)

    2022-10-10 10:45:54
  • asp之家 网络编程 m.aspxhome.com