首页 > 其他分享 >关于 Angular HTTP Interceptor 中 Request 和 Response 的 immutable 特性

关于 Angular HTTP Interceptor 中 Request 和 Response 的 immutable 特性

时间:2022-10-15 11:12:07浏览次数:54  
标签:body HTTP 请求 clone req Request immutable

尽管拦截器能够修改请求和响应,但 HttpRequest 和 HttpResponse 实例属性为 readonly,这意味着其具有 immutability 特性。

这种特性是 Angular 框架有意为之的设计:应用程序可能会在一个 HTTP 请求成功完成之前,多次重试请求。换言之,这意味着 Interceptor chain 可以多次重新处理(re-process)相同的请求。 如果拦截器可以修改原始请求对象,则重试操作将从修改后的请求开始,而不是从原始请求开始,这会给应用程序的处理引入极大的不确定性。

因此,Angular Interceptor 处理上下文中的 HTTP 请求和响应的 immutability 特性,确保拦截器在每次尝试中处理的是相同的请求。

TypeScript 阻止开发人员设置 HttpRequest 对象中具有 readonly 的属性,看个具体的例子:

// Typescript disallows the following assignment because req.url is readonly
req.url = req.url.replace('http://', 'https://');

如果应用程序里必须更改 HTTP Request,请先克隆它并修改克隆,然后再将其传递给 next.handle()。 可以在一个步骤中克隆和修改请求,如以下示例所示:

// clone request and replace 'http://' with 'https://' at the same time
const secureReq = req.clone({
  url: req.url.replace('http://', 'https://')
});
// send the cloned, "secure" request to the next handler.
return next.handle(secureReq);

下面是 SAP Spartacus Interceptor 中使用 clone 方法去修改一个 HTTP Request 的具体例子:

[图片]

TypeScript 的 readonly 属性,并不能阻止 Request body 字段被 deep update.

下列代码能工作,然而却是一个糟糕的设计,原因如前所述:如果该 Interceptor 被重复调用,则每次调用会在前一次调用修改的 HTTP Request 的基础上再次进行修改,不断造成 Side Effect:

req.body.name = req.body.name.trim(); // bad idea!

Angular 推荐的做法依次是:

  • 对 Request body 进行 copy,并修改 copy 版本
  • 使用 HTTP Request 的 clone 方法,克隆请求对象。
  • 用修改后的 body copy 版本,替换克隆出来的 HTTP 请求的 body 字段。

伪代码如下:

// copy the body and trim whitespace from the name property
const newBody = { ...body, name: body.name.trim() };
// clone request and set its body
const newReq = req.clone({ body: newBody });
// send the cloned request to the next handler.
return next.handle(newReq);

标签:body,HTTP,请求,clone,req,Request,immutable
From: https://www.cnblogs.com/sap-jerry/p/16793738.html

相关文章

  • JavaWeb学习4:Http
    1、什么是http超文本传输协议(HyperTextTransferProtocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。2、两个时代HTTP/1.0客户端可以与web服务器连接后,只......
  • Python Flask HTTP请求
    GET请求@app.route('/get',methods=["GET"])defget_():#返回字符串return'这是get请求' POST请求@app.route('/post',methods=["POST"])defpost......
  • javascript获取当前是http还是https
    我们经常需要获取网页的url,此时就会用到如下:document.location.protocol//判断是https:还是http:document.location.hostname//获取是localhost还是192.168.100.......
  • HTTPS的WEB SERVICE,数据量过大,客户要求压缩数据传输
    群里有人问:HTTPS的WEBSERVICE,数据量过大,客户要求压缩数据传输。然后看到侠之大者张老哥回复:sicf找到对应的服务选 YES然后再测试的时候发现记录一下。谢谢侠之大者提供......
  • Wireshark Lab: HTTP v7.0
    0.实验文件地址http://www-net.cs.umass.edu/wireshark-labs/Wireshark_HTTP_v7.0.pdf方法字段可以取不同的值:GET、POST、HEAD、PUT和DELETE。GET:请求服务器发送某个......
  • .Net Core redis 调用报错 '6000 Redis requests per hour' 解决 6000 此调用限制
    问题描述redis是一种基于内存,性能高效的NoSQL数据库,性能高主要就体现在数据交互耗时较短,能够段时快速的对用户的请求做出反应,所以在业务比较复杂或交互量需求大时,必然......
  • windows server2012服务器下PHPstudy配置ssl证书(https配置)
    准备: 阿里云云服务器阿里云购买的域名(已备案、已解析phpstudy:php7.1.13nts+Apachessl证书申请(我用的是阿里云上申请的证书,好像是免费用一年吧)步骤: 申请证书(这个很多方式,......
  • 调用HTTPS接口
    步骤1:打开浏览器-管理证书-导出证书到本地(常用方法,有些纯接口项目需要拿到证书和私钥)步骤2:在DOS窗口里,执行下面的语句把导出的.cer文件生成jmeter要求的.store文件(注我的......
  • 大名鼎鼎的Requests库用了什么编码风格?
     原文:https://www.kennethreitz.org/essays/kenneth-reitzs-code-style作者:KennethReitz原题:KennethReitz’sCodeStyle™  Requests的代码库使用PEP-8编码风格。......
  • Python爬虫之requests模块了解
    requests模块知识点:掌握headers参数的使用掌握发送带参数的请求掌握headers中携带cookie掌握cookies参数的使用掌握cookieJar的转换方法掌握超时参数timeout的使用掌......