代码之家  ›  专栏  ›  技术社区  ›  Wilt

处理多部分响应体的角度

  •  -1
  • Wilt  · 技术社区  · 7 年前

    this issue on GitHub ).

    HttpClient 只需返回 HttpResponse application/json 阻止可在my中访问的多部分响应 反对。

    如何正确处理角度内的多部分响应?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Wilt    7 年前

    this other post 在stackoverflow上创建了一个http拦截器类,该类显示如何解析多部分响应。 拦截器将第一个“application/json”部分作为多部分响应的响应体返回( multipart/mixed multipart/form-data multipart/related ). 通过映射,可以很容易地将其他内容类型的其他解析器添加到类中。

    import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { Observable } from 'rxjs';
    import { map } from 'rxjs/operators';
    
    @Injectable({
      providedIn: 'root',
    })
    
    export class MultipartInterceptService implements HttpInterceptor {
    
      private parserMap = {
        'application/json': JSON.parse,
      };
    
      private parseMultipart(multipart: string, boundary: string): any {
        const dataArray: string[] = multipart.split(`--${boundary}`);
        dataArray.shift();
        dataArray.forEach((dataBlock) => {
          const rows = dataBlock.split(/\r?\n/).splice(1, 4);
          if (rows.length < 1) {
            return;
          }
          const headers = rows.splice(0, 2);
          const body = rows.join('');
          if (headers.length > 1) {
            const pattern = /Content-Type: ([a-z\/+]+)/g;
            const match = pattern.exec(headers[0]);
            if (match === null) {
              throw Error('Unable to find Content-Type header value');
            }
            const contentType = match[1];
            if (this.parserMap.hasOwnProperty(contentType) === true) {
              return this.parserMap[contentType](body);
            }
          }
        });
        return false;
      }
    
      private parseResponse(response: HttpResponse<any>): HttpResponse<any> {
        const contentTypeHeaderValue = response.headers.get('Content-Type');
        const body = response.body;
        const contentTypeArray = contentTypeHeaderValue.split(';');
        const contentType = contentTypeArray[0];
        switch (contentType) {
          case 'multipart/related':
          case 'multipart/mixed':
          case 'multipart/form-data':
            const boundary = contentTypeArray[1].split('boundary=')[1];
            const parsed = this.parseMultipart(body, boundary);
            if (parsed === false) {
              throw Error('Unable to parse multipart response');
            }
            return response.clone({ body: parsed });
          default:
            return response;
        }
      }
    
      // intercept request and add parse custom response
      public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request)
          .pipe(
            map((response: HttpResponse<any>) => {
              if (response instanceof HttpResponse) {
                return this.parseResponse(response);
              }
            }),
          );
      }
    }
    

    代码从 Content-Type 响应头并使用此边界将响应体拆分为块。然后它尝试解析每个部分并返回第一个成功解析的部分 application/json

    注:

    推荐文章