下载文件,文件名乱码问题

C# .net framework 4.8 mvc 项目,做一个文件下载功能。

原项目是前端使用razor引擎方式做页面渲染的。

该项目原来就有一个模块是可供文件下载的,且文件名是中文。

但是我现在新增的这个模块,领导要求用js写,觉得razor太笨重。

后端有一个通用的DownloadHelper帮助类。

这个帮助类里已经封装过了设置Encode和请求头等信息。

使用原模块下载时,一切正常。

使用新模块下载时,当文件名是中文时,文件名是%e4%b8这种。

经过两天的调查,原模块与新模块对比测试,才发现原来是前端的问题。

核心代码:

// 提取文件名并去除引号
var encodedFileName = matches[1].replace(/['"]/g, '');
// 对文件名进行解码
var decodedFileName = decodeURIComponent(encodedFileName);

其实我这里前端封装的方法也是有问题的,

前端使用了AJAX获取文件流并手动生成下载链接,Blob+Url.createObjectURL,反而会丢失原始响应头中的Content-Disposition。

如果直接使用<a>标签,让浏览器自动去处理,反而不会有乱码问题。

### 解决前端下载文件文件名出现乱码问题 当遇到前端下载文件文件名出现乱码的情况,可以采取多种方法来确保文件名能够正确显示。以下是几种有效的解决方案: #### 方法一:使用 `Content-Disposition` 头部设置文件名编码 为了防止文件名乱码,在发起 HTTP 请求时可以通过设置响应头中的 `Content-Disposition` 来指定文件名及其编码方式[^1]。 ```javascript // 设置 Content-Disposition 响应头部 res.setHeader('Content-disposition', 'attachment; filename*=UTF-8\'\'' + encodeURIComponent(fileName)); ``` 这种方法适用于服务器端控制文件名的情形下,客户端浏览器会按照给定的编码解析文件名。 #### 方法二:利用 Blob 和 URL.createObjectURL 实现无窗口打开下载 对于仅限于前端操作而不涉及服务端修改权限的情况下,可以直接创建一个隐藏的 `<a>` 标签并通过 JavaScript 动态触发点击事件完成下载过程,同时自定义文件名以避免乱码现象发生。 ```html <!-- HTML 部分 --> <a id="downloadLink" style="display:none;"></a> <script type="text/javascript"> const downloadFile = (content, fileName) => { let blob = new Blob([content], {type : "application/octet-stream"}); let link = document.getElementById("downloadLink"); // 创建对象 URL 并赋值给 a 标签 href 属性 link.href = window.URL.createObjectURL(blob); link.download = decodeURIComponent(escape(window.atob(fileName))); // 对 base64 编码后的文件名解码 // 触发点击事件实现自动下载 link.click(); // 释放内存 window.URL.revokeObjectURL(link.href); }; </script> ``` 此代码片段展示了如何不依赖第三方库而手动构建下载链接,并通过适当的方式处理可能存在的特殊字符或中文问题造成的乱码情况。 #### 方法三:借助 js-file-download 库简化流程 如果项目允许引入外部依赖,则可考虑采用专门用于文件下载的 npm 包如 `js-file-download` ,它能帮助更方便地管理整个下载逻辑以及解决潜在的文字编码难题[^2]。 ```javascript import fileDownload from 'js-file-download'; api.GetDownload(param).then(response => { fileDownload(response.data, decodeURI(decodeURIComponent(escape(window.atob(response.headers['filename']))))); }); ``` 上述例子中假设 API 返回的数据已经包含了经过 Base64 或其他形式加密过的文件名字符串;实际应用时需根据具体情况调整相应的解密函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值