【问题标题】:How to add something to the body of request inside an Angular interceptor?如何在 Angular 拦截器内的请求正文中添加一些内容?
【发布时间】:2019-04-08 12:10:45
【问题描述】:

在这里我可以修改标题,因为有多个关于此功能的教程,但是:

@Injectable()
export class MyFirstInterceptor implements HttpInterceptor {

    constructor(private currentUserService: CurrentUserService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        console.log(JSON.stringify(req));

        const token: string = this.currentUserService.token;

        if (token) {
            req = req.clone({ headers: req.headers.set('Authorization', 'Bearer ' + token) });
        }

        if (!req.headers.has('Content-Type')) {
            req = req.clone({ headers: req.headers.set('Content-Type', 'application/json') });
        }

        req = req.clone({ headers: req.headers.set('Accept', 'application/json') });
        return next.handle(req);
    }
}

但就我而言,有一个令牌,我需要添加请求正文而不是请求标头,所以有什么方法可以修改正文。

更新:Mild Fuzz 的方法非常适合简单的发布请求 但如果它是 GET 请求和正文,我想添加到查询中 允许添加身体。最重要的是,当我尝试时它坏了 发送表单数据。 ...request.body 删除表单数据并 将其转换为JSONobject,这样我的图像就消失了。

【问题讨论】:

    标签: javascript angular api interceptor


    【解决方案1】:

    感谢 Mild Fuzz,这正是我想要的,但在我的情况下,我遇到了一些并发症,我能够解决一些额外的头痛问题。 这是我的最终实现:

      intercept(
        req: HttpRequest<any>, 
        next: HttpHandler
      ): Observable<HttpEvent<any>> {
    
        console.log('Intercepted!', req);
        const authService = this.injector.get(AuthService);
        const reqCloned =  this.handleBodyIn(req, localStorage.getItem('random_key'), 'random_key_added');
        const copiedReq = reqCloned;
        return next.handle(copiedReq);
      }
      handleBodyIn(req:HttpRequest<any>, tokenToAdd, tokenName) {
        if (req.method.toLowerCase() === 'post') {
          if (req.body instanceof FormData) {
            req =  req.clone({
              body: req.body.append(tokenName, tokenToAdd)
            })
          } else {
            const foo = {}; foo[tokenName] = tokenToAdd;
            req =  req.clone({
              body: {...req.body, ...foo}
            })
          }            
        } 
        if (req.method.toLowerCase() === 'get') {
          req = req.clone({
            params: req.params.set(tokenName, tokenName)
          });
        } 
        return req;    
      }
    }

    Here's the editor link if any one else wants to check.

    【讨论】:

    • 你可能会从 linter 中受益。它会捕获诸如双等号之类的东西
    【解决方案2】:

    这是一个工作示例:

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
            const clonedreq = req.clone({
                headers: req.headers.set("Authorization", "Bearer " + sessionStorage.getItem('userToken'))
            });
            return next.handle(clonedreq)
                .do(
                succ => {
                    if(succ["status"] != null && succ["status"] != undefined){
                        this.loaderService.handleResponse('regular');
                    }
                 },
                err => {
                    if (err.status === 401)
                        this.router.navigateByUrl('/Login');
                    this.loaderService.handleResponse('regular');
                }
            );
    }
    

    【讨论】:

    • 我会说一个完美的答案。但是请先完成这个问题。
    【解决方案3】:
     req = req.clone({ 
      headers: req.headers.set('Accept', 'application/json'),
      body: {...req.body, hello: 'world' }});
    

    这样的?

    【讨论】:

    • @BlackMamba - 如果它的 GET 或内容类型是流,您可以将令牌附加到 URL。
    • 感谢您的回答,它帮助我完成了任务。我授予了赏金,但我认为我的赏金已被接受,因为它适合我的用例。
    猜你喜欢
    • 2019-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    • 2015-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多