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