如何从响应中读取文件名 - ReactJs

5
我正在从服务器下载一个文件。在那里,我设置了一个文件名,我希望在前端读取它。以下是我在服务器上的操作方式:
string fileName = "SomeText" + DateTime.UtcNow.ToString() + ".csv";

return File(stream, "text/csv", fileName);

基本上我会返回不同类型的文件,有时是CSV格式,有时是XLSX格式,有时是PDF格式。因此,我想在前端获取文件名,这样我就可以将其保存为应该的格式,例如SomeText.pdf,它将自动保存在本地机器上的PDF格式中。
以下是我的前端代码:
getFileFromServer(params).then(response => {
  console.log('server response download:', response);
  const type = response.headers['content-type'];
  const blob = new Blob([response.data], { type: type, encoding: 'UTF-8' });
  //const url = window.URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = 'file.xlsx'; // Here I want to get rid of hardcoded value instead I want filename from server
  link.click();
  link.remove(); //  Probably needed to remove html element after downloading?
});

我在网络选项卡下的响应头部分看到了一个Content-Disposition,其中包含了该信息:

Content-Disposition: attachment; filename="SomeText22/08/2019 10:42:04.csv";

但我不知道它是否在我的响应中可用,以及如何在前端部分读取它,以便我可以替换。

link.download = 'file.xlsx';

通过服务器的路径 ..

非常感谢大家

祝好


你解决了吗?我也遇到了同样的问题。我从后端发送了content-disposition头,并且在浏览器的网络选项卡中也可以看到它。但是我无法在我的代码中检索它。它不在response.headers中。下面的两个答案对我都没有用。 - Muaz
@Muaz 我在前端创建了 switch case,使用可能的文件扩展名创建了枚举类型,当我查找文件时,例如“.txt”、“。csv”、“。xlsx”,我将该导出类型发送到服务器,当我收到响应时,我只是将在前端选择的类型分配给文件名,就这样。 - Roxy'Pro
3个回答

4

这是一种特殊类型的头信息,在前端获取这个头信息需要后端人员在服务器端进行设置。之后你就可以在响应中看到这个头信息。

response.headers.get("content-disposition")

我在项目中使用了以下代码

 downloadReport(url, data) {
    fetch("url of api")
      .then(async response => {
        const filename = response.headers
          .get("content-disposition")
          .split('"')[1];
        const text = await response.text();
        return { filename, text };
      })
      .then(responseText => this.download(responseText))
      .catch(error => {
        messageNotification("error", error.message);
        throw new Error(error.message);
      });
  }

3

要从客户端(前端)的Content-Disposition中获取文件名,您必须从服务器端(后端)获得许可。Spring用户可以使用

@CrossOrigin(value = {"*"}, exposedHeaders = {"Content-Disposition"})
@Controller
@RequestMapping("some endpoint")

在他们的控制器类中。

然后从前端,我们可以使用以下方式获取文件名。

const filename = response.headers['content-disposition'].split('filename=')[1];

希望这能帮到您。上述解决方案对我来说很有效。

该方法不是通用的,请检查其他情况。https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Disposition - Ievgen

2
你可以通过以下方式从Content-Disposition头中获取filename:filename。最初的回答。
getFileFromServer(params).then(response => {
  // your old code
  const [, filename] = response.headers['content-disposition'].split('filename=');
  const link = document.createElement('a');
  link.download = filename;
  // your old code
});

希望以下内容能对你有所帮助:

最初的回答


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接