原文:http://www.ttlsa.com/fastdfs/fastdfs-experience-sharing/
應用背景
文件被上傳到FastDFS后Storage服務端將返回的文件索引(FID),其中文件名是根據FastDFS自定義規則重新生成的,而不是原始文件名,例如: group2/M00/00/89/eQ6h3FKJf_PRl8p4AUz4wO8tqaA688.apk
使用http下載時如不加處理,顯示給用戶的文件名會是這樣的eQ6h3FKJf_PRl8p4AUz4wO8tqaA688.apk,這樣的用戶體驗很不好。由於FastDFS不會存儲原始文件名,也沒有提供恢復原始文件名的方法,所以需要應用系統自己想辦法恢復原始文件名。
解決方法
通過在項目中多次嘗試,找到一種較簡單的實現方法,實現過程如下:
一. 應用系統在上傳文件到FastDFS成功時將原始文件名和“文件索引(FID)”保存下來(例如:保存到數據庫)。
二. 用戶點擊下載的時用Nginx的域名和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.apk 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:121.14.161.48:9030 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.apk
返回包:
Response Headersview source Accept-Ranges:bytes Connection:keep-alive Content-Disposition:attachment;filename=filename.apk 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