在 Angular 中处理多部分响应主体

2024-04-29

我在 Angular 中收到多部分响应正文,但应用程序未正确处理响应。事实证明,Angular 中的 HttpClient 无法正确解析多部分响应主体(请参阅这个问题在 GitHub 上 https://github.com/angular/angular/issues/19507).

The HttpClient只需返回主体内的原始多部分响应HttpResponse反对,而我想要application/json阻止可在我的内部访问的多部分响应HttpResponse object.

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


我做了一个快速而肮脏的解决方案,深受启发这另一篇文章 https://stackoverflow.com/a/40657435/1697459在 stackoverflow 上并创建了一个 http 拦截器类,该类展示了如何解析多部分响应。 拦截器返回第一个“application/json”部分作为多部分响应的响应正文(multipart/mixed, multipart/form-data or 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阻止响应。

如果您有兴趣返回另一个代码块或者您想在最终响应中组合多个代码块,您将需要自己的解析器或更改逻辑。这需要对代码进行一些定制。

NOTE:该代码是实验性的,并且经过有限的测试,尚未准备好投入生产,使用时要小心。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Angular 中处理多部分响应主体 的相关文章

  • 从 Angular 2 动态表单的 API 设置值

    我正在尝试开始在 Angular 2 中创建动态表单 并且我正在使用 Angular 食谱中的设置here https angular io docs ts latest cookbook dynamic form html作为我的起点 我
  • Angular2:setTimeout仅调用一次

    我正在 Angular2 中实现需要使用的功能setTimeout My code public ngAfterViewInit void this authenticate loop private authenticate loop s
  • Angular2 + Laravel 与实时和 WebSockets

    我构建了一个应用程序 并计划与 Angular 2 和 laravel 进行实时战斗 例如 你按下 攻击 按钮 你的对手就会实时看到他的生命在下降 我的应用程序构建有 前端 角2 Backend PHP Laravel 5 2 现在我正在寻
  • Angular 2 Component - 访问 DOM(或创建没有模板的组件,纯粹来自 JS)

    尝试在这里使用 Angular 2 了解它仍处于 alpha 阶段 如何从组件访问 DOM 元素 具体来说 我想使用其他库 例如d3 http d3js org 从代码生成自定义 DOM 我想我需要创建一个组件并以某种方式插入组件生命周期以
  • 多部分 gzip 文件随机访问(Java 中)

    这可能属于 不太可行 或 不值得付出努力 的范畴 但事实就是如此 我正在尝试随机访问存储在多部分 gzip 文件中的记录 具体来说 我感兴趣的文件被压缩Heretrix http crawler archive org 弧形文件 如果您不熟
  • 如何从 Angular 7 中的另一个组件更新视图?

    我想从导航栏刷新我的卡集 该导航栏是应用程序组件 html所以我准备了刷新 功能 当它被调用时 它会更新变量 Cards 但不会将其呈现在ngFor在 html 元素上mainView html 如果我从 html 元素调用 它会渲染更新的
  • 如何使用 Web 套接字和 Angular CLI 设置代理

    我有一个使用 Angular CLI 构建的简单 Web 应用程序 我希望它使用网络套接字与后端通信 我已经编写了后端 并使用一个简单的 index html 页面进行了测试 服务器可以在套接字上发送和接收该页面 在我的 angular c
  • 您必须位于 angular-cli 项目中才能使用serve命令

    我正在尝试运行拖放示例dragula https github com valor software ng2 dragula 但是当我跑步时ng serve它抱怨 You have to be inside an angular cli p
  • 从父组件调用的子组件内的 Angular 2 ng2-bootstrap 模式

    很难解释这一点 我有一个简单的 ng2 bootstrap 模式示例 我将其扩展为包含主页的 Boostrap 4 Jumbotron 示例模板 现在 ng2 bootstrap 模式不执行任何操作 我可以看到this childModal
  • 如何在每个组件完成加载后在 Angular 2 中运行 jquery 函数

    我已经尝试了所有生命周期挂钩 但无法实现所需的结果 我需要的结果是触发一个函数 该函数在加载每个元素 组件 后初始化用于单个页面上不同元素的许多 jquery 插件 假设你有这个结构 主页 滑块 小部件 产品旋转器 ETC 这些元素中的每一
  • 导航嵌套组件时创建面包屑 (Angular 2)

    我正在为此苦苦挣扎 这个想法是有一个组件 当浏览子视图时更新面包屑 例如
  • 如何在 Angular @Input 中仅接受预定义值

    我的问题是 我在 a 中收到一个字符串值作为组件的参数 但我想限制可以用作参数的值 就像enum I use Input type string 但是在组件中 一切都可以引入type正如我之前所说 我需要将其限制为 3 个选项 例如Enum
  • 渲染作为 Prop 传入的 Component

    我怎样才能渲染一个StyledComponent它是作为道具传入的吗 我正在传递一个Spinner组件到我的BarComponent作为渲染的道具 我尝试使用 this props icon in my BarComponent在下面的示例
  • Rxjs、fromEvent处理多个事件

    在 rxjs 5 1 中处理同一 DOM 节点上的多个事件的最佳方法是什么 fromEvent element event name 但我一次只能指定一个事件 我要手柄scroll wheel touchmove touchend even
  • 如何将 Laravel 5.4 与 Angular 4 集成

    我知道如何创造完整的拉拉维尔 5 4自己的项目 我也知道如何使用创建 SPA角4 Problem 我不知道如何将 Laravel 与 Angular 集成 另外 我想使用 Laravel 5 4 作为后端 使用 Angular 4 作为前端
  • 警告:找不到父级 tsconfig.json

    我想修复警告 警告 找不到父级 tsconfig json 在打字稿中Errors tab in IntelliJ IDEA 2016 3 我的 TypeScript 代码位于src目录和我的 TypeScript 输出将是lib正如预期的
  • D3、TS 和 Angular 2

    我正在尝试将 D3 v4 与 Angular 2 Typescript 一起使用 我目前正在研究 D3 v4 我能够遵循 stackoverflow 中类似问题的一些答案 但没有成功 我已经导入了大部分 D3 库及其类型 我使用的是 TS
  • 在指令中动态添加 *ngIf

    如何动态地将 ngIf 添加到用属性指令修饰的元素 为了一个简单的实验 我尝试了这个 Directive selector lhUserHasRights export class UserHasRightsDirective implem
  • 在哪里存储角度中的 JWT 令牌?

    我正在使用 Django 和 Angular 构建一个应用程序 目前 我正在本地存储上存储后端发出的 JWT 但是 我担心 XSS 攻击 我应该使用仅 HTTP 的 cookie 来存储令牌吗 我还考虑将令牌存储在我的身份验证服务类中的变量
  • 从回调中访问状态

    我在从回调访问组件状态时遇到问题 国家的价值num更改正确 但此类更改对于加载时定义的回调函数不可见 import React useState from react class MyObject callback gt void cons

随机推荐