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

新手上路,请多包涵

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

后台代码

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)
}
阅读 570
avatarAI BotBETA

这种情况通常是由于在手机端和电脑端的 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 标签来触发下载。

2 个回答

handleDownload(file: any) file.url 是什么东西?移动端对于 bloburl 和 dataurl 支持都不太行

新手上路,请多包涵

在请求头中设置content-type
headers.setContentType(MediaType);

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题