当前位置: 首页 > 知识库问答 >
问题:

Angular 5/6:从ASP.NET Core API HTTP处理文件下载(具有友好文件名)

子车新立
2023-03-14

我目前有一个ASP.NET Core 2.1 APIendpoint,用户可以点击该endpoint下载CSV文件:

[HttpPost("Gimme")]
public IActionResult Gimme([FromBody] MyOptions options)
{
    MemoryStream reportStream = _reportGenerator.GenerateReportStream(options.StartDate, options.EndDate);

    return new FileStreamResult(reportStream, "text/csv") { FileDownloadName = "report.csv" };
}

我可以通过邮递员测试它,它返回一个CSV与正确的数据,没有问题。

输入Angular。我们与API交互的web站点使用一个角度驱动的单页应用程序。我已经搜索了关于如何处理来自APIendpoint的文件的各种方法,其中很多似乎都围绕着获取一个Blob并创建一个内联URL,然后通过JavaScript中的window.open()导航到该URL。或者创建内存中的A标记,然后调用click()

我的问题是:最新的Angular真的没有办法解决这个问题吗?我不是什么角度的专家,但我认为他们的网站上会有一个例子,或者一些内置的机制来向浏览器提供下载的文件。然而,这似乎涉及到很多黑客行为。

我当前的WIP解决方案确实会将文件返回到浏览器进行下载,但不管API中指定的文件名如何,它都是作为临时文件名(某种类似GUID的东西)下载的:

下面是我的组件类和服务类中的内容。我更新了downloadfile()方法,以使用此SO答案中提供的答案来使友好的文件名工作,但我仍然希望找到一个不那么复杂的解决方案。

// Component

DownloadReport(options: ReportOptions) {
    this._service.getCSV(options).subscribe(data => this.downloadFile(data));
}

downloadFile(blob: Blob) {
    const fileName = 'report.csv';
    if (navigator.msSaveBlob) {
        // IE 10+
        navigator.msSaveBlob(blob, fileName);
    } else {
        const link = document.createElement('a');
        const url = URL.createObjectURL(blob);
        link.setAttribute('href', url);
        link.setAttribute('download', fileName);
        link.style.visibility = 'hidden';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(url);
    }
}

// Service

getCSV(reportOptions: ReportOptions): Observable<any> {
    let headers = new HttpHeaders();
    headers = headers.set('Accept', 'text/csv');
    return this._httpClient
        .post(`${this.apiRoot}/Gimme`, reportOptions, { headers: headers, responseType: 'blob' })
        .catch(this.handleError);
}

正如您所看到的,我目前正在实现createobjecturlhack来使其工作(一个在Internet上找到的解决方案的混合)。有更好的办法吗?“最佳实践”之类的方式?

共有1个答案

施洛城
2023-03-14

这就是我用的。它基本上是一样的东西,你正在使用,但看起来更干净一点,我与锚键入。我研究了很长一段时间的正确的方法来做到这一点,但找不到一个非骇客的方法来做到这一点。

  download(): void {
    this.service.getFile({ id: id, name: name })
      .subscribe(data => {
        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
          //save file for IE
          window.navigator.msSaveOrOpenBlob(data, name);
        } else {
          const objectUrl: string = URL.createObjectURL(data);
          const a: HTMLAnchorElement = document.createElement('a') as HTMLAnchorElement;

          a.href = objectUrl;
          a.download = name;
          document.body.appendChild(a);
          a.click();

          document.body.removeChild(a);
          URL.revokeObjectURL(objectUrl);
        }
      });
  }
 类似资料:
  • 我有一个javascript应用程序,它向某个URL发送ajax POST请求。响应可能是一个JSON字符串,也可能是一个文件(作为附件)。我可以很容易地在ajax调用中检测到内容类型和内容配置,但是一旦检测到响应包含文件,我如何提供客户端下载它呢?我在这里读过很多类似的文章,但没有一篇能提供我想要的答案。 请,请,请不要发布建议我不应该为此使用ajax或者我应该重定向浏览器的答案,因为这些都不是

  • 问题内容: 我有一个JavaScript应用程序,可将ajax POST请求发送到某个URL。响应可能是JSON字符串,也可能是文件(作为附件)。我可以在ajax调用中轻松检测Content-Type和Content- Disposition,但是一旦检测到响应中包含文件,如何为客户端提供下载文件?我在这里阅读了许多类似的主题,但是没有一个主题提供我想要的答案。 拜托,拜托,请不要发布暗示我不应该

  • 我想创建带有Spring批处理Rest控制器和动态输入文件名的项目。 我的代码:Rest控制器 公共类FileNameController{ } 作业配置: @EnableBatchProcessing公共类JobConfig{ } 我写网址的时候:http://localhost:8080/launch job?fileName=djecc5cpt.csv控制台打印: SQL语法[SELECTJ

  • 问题内容: 我想知道它有Safari Selenium Webdriver所需的任何功能或选项设置,可以将文件保存到特定位置,就像我们为firefox驱动程序所做的那样。 还想禁用文件保存对话框的弹出窗口。 问候,Himanshu 问题答案: 您可以检查以下链接。你工作吗,但不确定 http://code.google.com/p/selenium/wiki/DesiredCapabilities

  • 本文向大家介绍php文件下载处理方法分析,包括了php文件下载处理方法分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php文件下载的处理方法。分享给大家供大家参考。具体分析如下: php能够处理多种条件的文件下载,先来看下面示例: 分析上述代码: 第一行代码是强制下载; 第二行代码是给下载的内容指定一个名字; 第三行代码是把下载的内容读进文件中。   一直以为要在一个页面中同时下载多

  • 问题内容: 我有一个需要从网站下载PDF的要求。PDF需要在代码中生成,我认为这将是freemarker和iText等PDF生成框架的结合。还有更好的办法吗? 但是,我的主要问题是如何允许用户通过Spring Controller下载文件? 问题答案: 一般来说,当你拥有时,你可以在其中编写任何内容。你可以将此输出流作为将生成的PDF放置到生成器的地方。另外,如果你知道要发送的文件类型,则可以设置