需求
- 統計靜態文件的下載次數;
- 判斷用戶是否有下載權限;
- 根據用戶指定下載速度;
- 根據Referer判斷是否需要防盜鏈;
- 根據用戶屬性限制下載速度;
X-Accel-Redirect
This allows you to handle authentication, logging or whatever else you please in your backend and then have NGINX handle serving the contents from redirected location to the end user, thus freeing up the backend to handle other requests. This feature is commonly known as X-Sendfile.
這個功能允許你在後端處理權限,日誌或任何你想幹的,Nginx提供內容服務給終端用戶從重定向後的路徑,因此可以釋放後端去處理其他請求(直接由Nginx提供IO,而不是後端服務)。這個功能類似 X-Sendfile 。
不同Web
服務器,相同功能,不同的標識:
nginx: X-Accel-Redirect
squid: X-Accelerator-Vary
apache: X-Sendfile
lighttpd: X-Sendfile/X-LIGHTTPD-send-file
X-Accel-Limit-Rate
限制下載速度,單位字節。默認不限速度。
X-Accel-Buffering
設置此連接的代理緩存,將此設置爲no
將允許適用於Comet
和HTTP
流式應用程序的無緩衝響應。將此設置爲yes
將允許響應被緩存。默認yes
。
X-Accel-Expires
如果已傳輸過的文件被緩存下載,設置Nginx
文件緩存過期時間,單位秒。默認不過期。
X-Accel-Charset
設置文件字符集,默認UTF-8
使用條件
- 必須有
Nginx
作爲後端服務的代理; - 必須訪問
Nginx
的代理地址,直接訪問後端服務Nginx
會報404
; - 可自行配置
Content-Type
來控制是下載(application/octet-stream
)還是展示(image/jpeg
等);
代碼實現
Nginx
監聽9876
端口。Nginx
代理後端服務的8080
端口。- 設置
/testAccel
路徑爲internal
,指定具體文件存儲的磁盤位置。 - 後端服務接收到文件下載請求,處理業務邏輯後
X-Accel-Redirect
到/testAccel
路徑。 Nginx
收到後端返回信息中的X-Accel-Redirect
請求頭,接管文件下載或顯示任務。- 請求路徑:http://localhost:9876/file/download/1234.jpg。
Nginx
配置:
location / { #root html; root F:/web/; index index.html index.htm; try_files $uri $uri/ /index.html; } location /testAccel { internal; alias F:/web/testAccel/file; } location /file { proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8080; }
Java
代碼
注意fileName
添加:.+
,或者獲取不到文件後綴名。
@GetMapping("/file/download/{fileName:.+}") public void download(HttpServletRequest request, HttpServletResponse response, @PathVariable("fileName") String fileName) { //統計 //鑑權 //判斷Referer String referer = request.getHeader("Referer"); System.out.println(referer); String prefix = "/testAccel"; // 在這之前進行一些必要的處理,比如鑑權,或者其它的處理邏輯。 // 通過X-Accel-Redirect返回在nginx中的實際下載地址 response.setHeader("X-Accel-Redirect", prefix + "/" + fileName); response.setHeader("X-Accel-Limit-Rate", "1024");//限速,單位字節,默認不限 response.setHeader("X-Accel-Buffering", "yes");//是否使用Nginx緩存,默認yes }
如果直接訪問路徑:http://localhost:9876/testAccel/1234.jpg,就會報404錯誤
參考:
https://www.zhangbj.com/p/507.html