应用背景:
文件被上传到FastDFS后Storage服务端将返回的文件索引(FID),其中文件名是根据FastDFS自定义规则重新生成的,而不是原始文件名,例如: group1/M00/00/89/op6h3FKJf_12Ep4AUz4wO8tqaB889.png
使用http下载时如不加处理,显示给用户的文件名会是这样的op6h3FKJf_12Ep4AUz4wO8tqaB889.png,这样的用户体验很不好。由于FastDFS不会存储原始文件名,也没有提供恢复原始文件名的方法,所以需要应用系统自己想办法恢复原始文件名。
解决方法
通过在项目中多次尝试,找到一种较简单的实现方法,实现过程如下:
一. 应用系统在上传文件到FastDFS成功时将原始文件名和“文件索引(FID)”保存下来(例如:保存到数据库)。
二. 用户点击下载的时用Nginx的域名和FID拼出url,然后在url后面增加一个参数,指定原始文件名。例如:http://192.168.1.23:8081/group1/M00/00/89/op6h3FKJf_12Ep4AUz4wO8tqaB889.png?attname=filename.png
三. 在Nginx上进行如下配置,这样Nginx就会截获url中的参数attname,在Http响应头里面加上字段 Content-Disposition “attachment;filename=$arg_attname”。
location /group1/M00 {
root /data/store/data;
if ($arg_attname ~ "^(.*).png") {
add_header Content-Disposition "attachment;filename=$arg_attname";
}
ngx_fastdfs_module;
}
四. 浏览器发现响应头里面有Content-Disposition “attachment;filename=$arg_attname”时,就会把文件名显示成filename指定的名称。
完整的请求和响应消息如下:
请求包:
Request URL:http://192.168.1.23:8081/group1/M00/00/89/op6h3FKJf_12Ep4AUz4wO8tqaB889.png?attname=filename.png
Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6
Connection:keep-alive
Host:192.168.1.23:8081
Referer:http://appandroidpcfront.test.uae.uc.cn/apps
User-Agent:Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
Query String Parametersview sourceview URL encoded
attname:filename.png
返回包:
Response Headersview source
Accept-Ranges:bytes
Connection:keep-alive
Content-Disposition:attachment;filename=filename.png
Content-Length:21821632
Date:Thu, 28 Nov 2013 11:40:46 GMT
Last-Modified:Mon, 18 Nov 2013 02:48:19 GMT
Server:nginx/1.4.3