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

java - ResponseEntity 文件下载,电脑下载可以正常打开,手机下载无法打开或打开乱码,这种情况是因为什么?

蓝昊天
2023-09-28

下载文件功能,电脑下载可以正常打开,手机下载无法打开,或者打开乱码

后台代码

HttpStatus statusCode = HttpStatus.OK;HttpHeaders headers = new HttpHeaders();if (download) {    String fileName = new String(r.getName().getBytes(), "ISO8859-1");    headers.add("Content-Disposition", "attachment;filename=" + fileName);}Resource resource = resourceLoader.getResource("file:" + path + "/" + id);InputStream in = resource.getInputStream();byte[] body = new byte[in.available()];in.read(body);ResponseEntity<byte[]> streamResponse = new ResponseEntity(body, headers, statusCode);return streamResponse;

前端下载

function handleDownload(file: any) {  console.log(file)  let a = document.createElement('a')  let event = new MouseEvent('click')  a.download = file.name  a.href = file.url  a.dispatchEvent(event)}

共有1个答案

蔚琦
2023-09-28

这种情况通常是由于在手机端和电脑端的 HTTP 响应头处理方式不同导致的。

在电脑端,浏览器会正确处理你设置的 "Content-Disposition" 响应头,这会告诉浏览器将这个响应内容作为一个文件来处理,因此可以直接打开下载的文件。

但在手机端,一些浏览器(例如,QQ 浏览器等)可能不会完全按照标准的 HTTP 协议来处理 "Content-Disposition" 响应头。它们可能只获取文件的 URL,而忽略了你设置的文件名。这会导致下载的文件没有正确的文件名,或者下载的文件内容出现乱码。

要解决这个问题,一种可能的解决方案是尝试使用不同的响应头设置,或者在前端代码中处理文件名和下载。例如:

后台代码:

HttpStatus statusCode = HttpStatus.OK;HttpHeaders headers = new HttpHeaders();if (download) {    String fileName = new String(r.getName().getBytes(), "ISO8859-1");    headers.add("Content-Disposition", "attachment; filename*=UTF-8''" + fileName); // 使用带编码的 filename* 参数}Resource resource = resourceLoader.getResource("file:" + path + "/" + id);InputStream in = resource.getInputStream();byte[] body = new byte[in.available()];in.read(body);ResponseEntity<byte[]> streamResponse = new ResponseEntity(body, headers, statusCode);return streamResponse;

这段代码中,我们使用了 "filename*=" 的参数,它允许我们指定一个包含非 ASCII 字符的文件名。同时,它还考虑到了编码的问题。

前端下载:

function handleDownload(file: any) {  let a = document.createElement('a')  let url = file.url;  let filename = file.name;  let blob = new Blob([decodeURIComponent(url.split(',')[1])], {type: 'text/plain'});   let url = URL.createObjectURL(blob);   a.download = filename;  //设置下载的文件名  a.href = url;  //设置下载的链接  document.body.appendChild(a);   a.click();   document.body.removeChild(a);}

这段代码通过解码 URL 中的内容,并创建一个 Blob 对象来获取文件内容。然后创建一个隐藏的 a 标签并设置其 href 属性为 Blob 对象的 URL。最后通过模拟点击这个 a 标签来触发下载。

 类似资料:
  • VUE DJANGO 可以下载文件,但是打不开 只有txt格式的文件可以正常打开 返回的response中的data均为乱码 求帮助解决

  • 使用Cordova/PhoneGap 3.3.0,我使用FileTransfer插件下载一个文件,然后尝试使用InAppBrowser插件打开它。我可以成功下载该文件,并将其放置在临时目录中。由于文件插件现在使用URL模式,我无法确定如何将正确的URL/路径传递到<code>窗口。打开InAppBrowser插件的方法。我也找不到任何相关文件。我能找到的所有“下载并打开”文档都是过时的,并且是UR

  • 问题内容: 我有一个生成PDF的动作类。该适当地设定。 我action 通过Ajax调用来称呼它。我不知道将流传输到浏览器的方法。我尝试了几件事,但没有任何效果。 上面给出了错误: 问题答案: 你不必为此使用Ajax。只是一个环节是不够的,如果你设置到服务器端代码。这样,如果你最关心的是父页面将保持打开状态(为什么你会为此而不必要地选择Ajax?)。此外,没有办法很好地同步处理这个问题。PDF不是

  • A)有没有一种方法可以下载在Chrome中使用脚本显式打开的PDF?B)有没有一种方法可以从打开的网页中提取URL,然后反馈到程序中下载?

  • 问题内容: 我有一个生成PDF的动作类。该适当地设定。 我 通过Ajax调用来称呼它。我不知道将流传输到浏览器的方法。我尝试了几件事,但没有任何效果。 上面给出了错误: 您的浏览器发送了该服务器无法理解的请求。 问题答案: 您不必为此使用Ajax。只是一个环节是不够的,如果你设置到服务器端代码。这样,如果您最关心的是父页面将保持打开状态(为什么您会为此而不必要地选择Ajax?)。此外,没有办法很好

  • 我正试图用reactJS下载一个xlsx文件,但当我在下载后试图打开我的文件时,我收到了这条消息: “Excel无法打开文件‘file.xlsx’,因为文件格式或文件扩展名无效。请验证文件是否已损坏,以及文件扩展名是否与文件格式匹配。” 这是前端代码: 为什么我得到这个错误?请谁来帮帮我,我被困在这个3周 [编辑1] 我尝试下载的文件是在后端构建的,基本上我获取数据库上的值并使用Apache po