当前位置: 首页 > Web前端 > HTML5

关于AngularHTTP拦截器中Request和Response的不可变属性

时间:2023-04-05 11:02:05 HTML5

尽管拦截器可以修改请求和响应,但是HttpRequest和HttpResponse的实例属性是只读的,这意味着它们具有不可变属性。此行为是Angular框架设计的:应用程序可能会在成功完成之前多次重试HTTP请求。换句话说,这意味着拦截器链可以多次重新处理同一个请求。如果拦截器可以修改原始请求对象,重试操作将从修改后的请求开始,而不是从原始请求开始,这给应用程序的处理引入了很大的不确定性。因此,Angular拦截器在上下文中处理HTTP请求和响应的不变性特性,确保拦截器在每次尝试时处理相同的请求。TypeScript不允许开发者在HttpRequest对象中设置readonly属性,看具体例子://Typescriptdisallowsthefollowingassignmentbecausereq.urlisreadonlyreq.url=req.url.replace('http://','https://');如果必须在应用程序中更改HTTP请求,请先克隆它并在将其传递给next.handle()之前修改克隆。一个请求可以一步完成克隆和修改,如下例所示:req.url.replace('http://','https://')});//将克隆的“安全”请求发送到下一个处理程序。returnnext.handle(secureReq);以下是在SAPSpartacusInterceptor中使用clone方法修改HTTPRequest的具体示例:[Image]TypeScript的readonly属性不会阻止Requestbody字段被深度更新。下面的代码是可以运行的,但是设计的很差,原因如前所述:如果重复调用Interceptor,每次调用都会在上一次调用修改的HTTPRequest的基础上再次修改,会不断造成SideEffect:req.body.name=req.body.name.trim();//不好idea推荐的方法!Angular是:复制Requestbody,修改复制版本使用HTTPRequest的clone方法克隆请求对象。将克隆的HTTP请求的主体字段替换为主体副本的修改版本。伪代码如下://从namepropertyconstnewBody={...body,name:body.name.trim()}中复制body和修剪空格//克隆请求并设置它的bodyconstnewReq=req.clone({body:newBody});//将克隆的请求发送到下一个处理程序。接下来返回。句柄(新请求);