首页 > 解决方案 > 使用 Angular 的 HttpClient 发出返回 PDF 的 POST 请求

问题描述

我正在使用返回 PDF 作为响应的 Web API 服务 ( DocRaptor )。在最初使用 API 时,我能够生成 PDF 并在他们的网站上查看 PDF。我收到一个 200 状态代码,告诉我响应成功。但是,使用以下代码在 Angular 端仍将帖子的结果作为错误返回:

    return this.http
  .post("https://docraptor.com/docs", {
    headers: {
      "Content-Type": "application/json"
    },
    user_credentials: "WEB_API_KEY",
    doc: {
      test: true,
      name: "testDocument.pdf",
      document_content: documentContent,
      type: "pdf"
    }
  })
  .subscribe(
    res => {
      console.log(res);
    },
    err => {
      console.log("Error occured: " + err);
    }
  );

我假设这是因为代码期望 JSON 作为结果,而 API 返回了 PDF。

Angular 关于请求非 JSON 数据的文档没有详细说明如何使用 HttpClient 使用响应(DocRaptor 也没有就此问题)。调试时,我无法告诉(使用 Chrome 中的网络选项卡)API 调用甚至正在发送,或者使用下面的代码返回响应。这可能是下面语法中的一个问题,但下面的代码是我使用我知道可用的文档尝试过的一种方法:

   return this.http
  .post("https://docraptor.com/docs", {
    responseType: "blob",
    headers: {
      "Content-Type": "application/json",
      Accept: "application/pdf"
    },
    user_credentials: "WEB_API_KEY",
    doc: {
      test: true,
      name: "testDocument.pdf",
      document_content: documentContent,
      type: "pdf"
    }
  })
  .pipe(tap(data => this.downloadFile(data, "application/pdf")));

更新:

我已经按照这里的回复中的建议重新构建了我的代码。但是,我仍然收到原始错误,即我从 DocRaptor API 返回 200 状态,但 Angular 的 HttpClient 没有将响应解析为 PDF。我已在标题中添加以接受 PDF,但我仍然收到一条错误消息“位置 0 处的 JSON 中的意外令牌 %”。

repl.component.ts

  generatePdf() {
    var htmlCard = this.cards.filter((card: Card) => card.language === "html")[0];
    var cssCard = this.cards.filter((card: Card) => card.language === "css")[0];

    var documentContent = this.generateCode(
      htmlCard.editorContent,
      cssCard.editorContent
    );

    this.docRaptorService.generatePdf(documentContent).subscribe(results => {
      let blob = results;
      let filename = "testDocument.pdf";
      FileSaver.saveAs(blob, filename);
    });
  }

doc-raptor.service.ts

  generatePdf(documentContent: string) {
    return this.http
      .post("https://docraptor.com/docs", {
        headers: {
          "Content-Type": "application/json",
          Accept: "application/pdf"
        },
        user_credentials: "WEB_API_KEY",
        doc: {
          test: true,
          name: "testDocument.pdf",
          document_content: documentContent,
          type: "pdf"
        },
        responseType: "blob"
      })
      .pipe(
        tap(
          data => console.log(documentContent, data),
          error => console.log(documentContent, error)
        )
      );
  }

标签: angularpdfhttp-postpdf-generationangular-httpclient

解决方案


 .pipe(tap(data => this.downloadFile(data, "application/pdf")));

你必须先到subscribe一个Observable它才会做任何事情。Angular 示例返回Observable带有tap“附加”运算符的 。您自己的示例正在返回Subscription,这对调用您的方法的任何内容都无用。

这是 Angular 服务的推荐设计模式;该服务创建Observable,这就像一个工作流和数据转换的合同,然后调用者可以subscribe访问它并获得工作的结果。


推荐阅读