使用 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 客户端应用重新将数据渲染到视图中。
我们可以通过创建 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


猜你喜欢
- 今天有一位同学给了我一个excel文件,要求读取某些行,某些列,然后我试着做了一个demo,这里分享出来,希望能帮到大家:首先安装xlrd:
- 相关验证码文章:asp制作验证码的方法 轩魂ASP中文验证码下载 先产生一个4位数的随机码源代码:ychar="0,1,2,3,4
- 资源React-16.8.*react-router-dom-4.3.*TypeScript-3.5.*webpack-4.*eslint-
- 使用torch.utils.data.Dataset类 处理图片数据时,1. 我们需要定义三个基本的函数,以下是基本流程class our_
- 前言今天在编码中,看到了一个非常经典的接口用法如下,于是查阅了相关资料,发现此种写法为接口型函数,本文对此做了细致的阐述。// A Gett
- 1 常规错误的yum安装方法:在前文中记述了CentOS 6.5系统中通过yum方式快速地搭建了LNMP环境,那么是否也能在CentOS 7
- windows server 2016 与 sql server 2016 都可用允许不许要加入AD ,管理方面省了挺多操作,也不用担心域控
- CSS对浏览器的兼容性有时让人很头疼,或许当你了解当中的技巧跟原理,就会觉得也不是难事,从网上收集了IE7,6与Fireofx的兼容性处理技
- 举个例子:q=[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]我想获取其中值等于7的那个值的下标,以便于用于其
- 先备份数据库,再用下面的办法: USE MASTER GO SP_CONFIGURE 'ALLOW UPDATES',1 R
- 关于mysql数据库在Linux下的应用一直以来都是我认为比较棘手的,这次通过搭建Linux学习环境顺便研究和学习Mysql数据库在Linu
- 本文实例为大家分享了python opencv识别图像轮廓的具体代码,供大家参考,具体内容如下要求:用矩形或者圆形框住图片中的云朵(不要求全
- 1、灵活运用样式熟悉网页设计的网友就知道,调用Style的方法很多,我们可以单击鼠标右键选择Custo
- 1. 根据属性ID值进行定位def test_find_element_by_id(self): # 定位搜索文本框  
- 前言相信我,只要记住本文的 7️⃣ 步口诀,就能彻底掌握 JS 中的 this 指向。先念口诀:箭头函数、new、bind、apply 和
- 前言最近在工作经常会碰到对字符串进行去重操作,下面就给大家列出用Python如何处理的,话不多说了,来一起看看详细的介绍吧。比如说,要拿下面
- 问题描述使用 Navicat 导入之前转储好的 sql 文件,报错错误原因在信息日志当中往上翻,发现没有选择数据库,所以报错的原因就是没有提
- 天猫将商品加入购物车会有一个抛物线动画,告诉用户操作成功以及购物车的位置,业务中需要用到类似的效果,记录一下实现过程备忘,先上demo&nb
- 前言作为一个数据分析师,应该信奉一句话——“一图胜千言”。不过这里要说的并不是数据可视化,而是一款全民向的产品形态——表情包!!!!表情包不
- Scrapy回调函数回调方法示例:yield Request(url=self.base_url + 'QueryInfo'