【问题标题】:How to create a json file and then return it in a get request back to react app如何创建一个 json 文件,然后在获取请求中返回它以响应应用程序
【发布时间】:2019-11-01 22:02:00
【问题描述】:

我正在尝试创建一个 JSON 文件 sample.json,并且我正在尝试在我的 Spring Boot 后端控制器中创建此文件,并能够将其发送到我的 React 应用程序,它将触发将文件下载到客户端

我想确保我实际上是从 http get 请求给出的响应中返回实际文件,并且我想知道如何触发该实际响应的下载 反应

fetch('/api/download')
  .then((res) => {
     return res.blob();
  }).then((body) => {
      console.log(body);
      setTimeout(() => {
         URL.createObjectURL(body)
      }, 300);
  }).catch((error) => {
     console.log(error);
  })

我的最终目标是能够让后端生成的文件通过获取请求并能够触发下载,请告诉我这是怎么可能的。谢谢。

【问题讨论】:

  • 为什么你的fetch 有一个then 作为第二个处理程序不返回任何东西? fetch 获取 URL 内容,第一个 then 获取结果网络对象,提取正文,然后转发。第二个then 得到了那个身体,并且有效地什么都不做。是的,它“做”了一些事情,但是结果被丢弃了,因为(a)你没有返回任何东西,(b)“做”发生在超时,所以将在完全不同的范围内运行,并且完全独立于承诺链。为什么你的第二个 then 不是 .then( body => URL.createObjectURL(body))
  • @Mike'Pomax'Kamermans 可以丢弃第二个 then 函数是我的 spring 代码返回一个实际文件,我如何能够用我返回的 body 触发下载?
  • 在我们回答这个问题之前,您能否将您的问题缩小到或者询问服务器端或客户端代码?您的端点工作(它向您发送您需要的数据)并且与实际问题无关,或者您的客户端代码工作(我假设这是您遇到问题的部分)并且 it i> 不应该出现在帖子中。尽量保留您的问题as focused on only the problem at hand
  • @Mike'Pomax'Kamermans 我已经编辑了这个问题,向您展示我的客户端代码是什么以及我如何尝试检索我制作的 JSON 文件的 blob,我想触发该文件的下载。
  • 谢谢。顺便说一句,为什么是setTimeout?您已经在异步工作了,那么您认为添加它有什么好处?

标签: java json reactjs spring-boot fetch


【解决方案1】:

最简单的方法是不使用fetch,而是使用普通的链接元素:

<a href="/api/download" download="sample.json">Click to download</a>

在所有现代浏览器中,download 属性将导致浏览器将链接响应保存为文件。不需要fetch

但是,如果您绝对需要 fetch 操作,那么您基本上可以在 JS 本身中执行此操作:获取您的结果,然后创建一个 &lt;a&gt;,将其 href 属性设置为文件 blob,并确保download 属性已设置:

fetch(...)
.then(res => res.blob())
.then(blob => {
  const blobURL = URL.createObjectURL(blob);

  // create our <a> to force a download for the response
  const dl = document.createElement(`a`);
  dl.href = blobURL;
  dl.download = `sample.json`;

  // In order for the link to "trigger" we need to add it to the document.
  // If we don't, dl.click() won't do anything. So add it, click it, then remove it.
  dl.style.display = `none`;
  document.body.appendChild(dl);
  dl.click();
  document.body.removeChild(dl);
});

【讨论】:

  • 所以你基本上只是显示了一个标签,并且在启动下载的时钟之后立即摆脱了标签
  • 它从不显示,因为它有 display:none。它只需要在 DOM 中才能让点击真正起作用,一旦它被点击,就不再需要它了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 2020-03-14
  • 2014-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多