Nginx伺服器內部重定向
Java web編程中經常涉及到重定向的問題,servlet實現了兩種重定向的方式:伺服器內部重定向(也叫forward,請求轉發),和客戶端重定向(redirect)。
forward是服務端行為,還是一個完整的http請求,對用戶來說是透明的;而redirect是客戶端的重定向,用戶能明顯看見url發生了改變,因為服務端在第一次的http響應中發送的是一個跳轉請求,可以是發送一個301或302的http響應,在http頭中指定location即可,也可以是200響應,在html中設置<meta http-equiv="refresh" content="0;url=xxx">標籤,指定跳轉的url即可。servlet的實現方式是定義了302狀態碼,指定location來實現跳轉。
大多數的web應用伺服器都會在前端加上一個nginx作為反向代理層,目地為了安全或者負載均衡,nginx對於靜態文件的處理能力比較高效,往往會有這種需求:由web應用伺服器做動態的下載許可權的驗證,然後把下載的事情交給nginx去做,同時又不想直接把文件地址暴露給用戶,於是必須使用到nginx服務端重定向的技術。回想一下nginx本身做反向代理的能力,設置一個proxy_pass,本身就起到了隱藏背後url的功能,只不過是寫死在配置文件中的,這裡的需求是一個下載請求過來以後,web應用伺服器處理完驗證邏輯後才代理到其他的url,所以這個代理的請求必須由web應用伺服器自己來發。
nginx提供了X-Accel-Redirect的關鍵字,web應用伺服器只要在響應的header中加上X-Accel-Redirect欄位,值為跳轉的uri,nginx會自動攔截這個http響應,然後在內部重定向到這個uri的位置,同時nginx必須配置internal的proxy_pass,表示這個反向代理只被內部使用,用戶直接訪問這個uri,會404。
server{n listen 80;n server_name localhost;n location /protect {n proxy_pass http://www.qq.com;n internal;n }n location / {n proxy_pass http://127.0.0.1:8089/;n }n}n
比如請求http://localhost/test, 應用伺服器在test處理結尾加上
response.addHeader("X-Accel-Redirect", "/protect")n
瀏覽器會返回騰訊的首頁,而url仍然是http://localhost/test, 即實現nginx伺服器內部重定向。
推薦閱讀:
※【Flask/React】本人BLOG的緩存實現
※使用nginx反向代理到谷歌可行嗎?
※Nginx 反向代理為什麼可以提高網站性能?