文章目录
- 1. 通过链接直接下载
- 2. 通过数据流下载
1. 通过链接直接下载
后端代码:
response.setCharacterEncoding(StandardCharsets.UTF_8.name()); // 字符集编码
response.setContentType("application/octet-stream"); // 返回内容的MIME类型
response.addHeader("Content-disposition", "attachment;filename=" + fileName + ";filename*=UTF-8" + fileName); // 内容描述
response.addHeader("Access-Control-Allow-Origin", "*"); // 实现跨域
/**
* 编码格式转换
*
* @param request 请求
* @param pFileName 文件名称
* @return String
* @throws UnsupportedEncodingException
*/
private String encodeChineseDownloadFileName(HttpServletRequest request, String pFileName)
throws UnsupportedEncodingException {
String filename;
String agent = request.getHeader("USER-AGENT");
if (null != agent) {
if (-1 != agent.indexOf("Firefox")) {
filename = "=?UTF-8?B?" + (new String(Base64.decode(pFileName.getBytes(StandardCharsets.UTF_8)))) + "?=";
} else if (-1 != agent.indexOf("Chrome")) {
filename = new String(pFileName.getBytes(), StandardCharsets.ISO_8859_1);
} else {//IE7+
filename = URLEncoder.encode(pFileName, StandardCharsets.UTF_8.name());
}
} else {
filename = pFileName;
}
return filename;
}
前端代码:
const elink = document.createElement('a') // 创建a标签
// elink.download = fileName // 重命名文件
elink.style.display = 'none'
elink.href = url
document.body.appendChild(elink)
elink.click() // 触发链接
document.body.removeChild(elink)
2. 通过数据流下载
通过数据流下载,下载时的文件名称就和Content-disposition中的filename关系不大
后端代码:
fileName = URLEncoder.encode(pFileName, StandardCharsets.UTF_8.name());
response.setCharacterEncoding(StandardCharsets.UTF_8.name()); // 字符集编码
response.setContentType("application/octet-stream"); // 返回内容的MIME类型
response.addHeader("Content-disposition", "attachment;filename=" + fileName + ";filename*=UTF-8" + fileName); // 内容描述
response.addHeader("Access-Control-Allow-Origin", "*"); // 实现跨域
// 列表哪些header可以作为响应的一部分暴露给外部(除了默认的七种,其他的是不暴露给外部的)
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
前端代码:
getFileName(fileName, response) {
// 需要响应设置此header暴露给外部,才能获取到
let contentDisposition = response.headers['content-disposition']
if (contentDisposition) {
// 正则获取filename的值
let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
let matches = filenameRegex.exec(contentDisposition)
if (matches != null && matches[1]) {
fileName = matches[1].replace(/['"]/g, '')
}
// 通过 URLEncoder.encode(pFileName, StandardCharsets.UTF_8.name()) 加密编码的, 使用decodeURI(fileName) 解密
fileName = decodeURI(fileName)
// 通过 new String(pFileName.getBytes(), StandardCharsets.ISO_8859_1) 加密编码的, 使用decodeURI(escape(fileName)) 解密
// fileName = decodeURI(escape(fileName))
}
return fileName
}
通过数据流下载文件:https://blog.csdn/besto229/article/details/112305428
更多推荐
文件下载 Content-Disposition中filename中文乱码解决
发布评论