亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 網站 > Nginx > 正文

nginx代理多次302的解決方法(nginx Follow 302)

2024-08-30 12:30:06
字體:
來源:轉載
供稿:網友

用proxy_intercept_errors和recursive_error_pages代理多次302

302是HTTP協議中的一個經常被使用狀態碼,是多種重定向方式的一種,其語義經常被解釋為“Moved Temporarily”。這里順帶提一下,現實中用到的302多為誤用(與303,307混用),在HTTP/1.1中,它的語義為“Found”.

302有時候很明顯,有時候又比較隱蔽。最簡單的情況,是當我們在瀏覽器中輸入一個網址A,然后瀏覽器地址欄會自動跳到B,進而打開一個網頁,這種情況就很可能是302。

比較隱蔽的情況經常發生在嵌入到網頁的播放器中。例如,當你打開一個優酷視頻播放頁面時,抓包觀察一下就會經常發現302的影子。但由于這些url并不是直接在瀏覽器中打開的,所以在瀏覽器的地址欄看不到變化,當然,如果將這些具體的url特意挑出來復制到瀏覽器地址欄里,還是可以觀察到的。

上一段提到了優酷。其實現在多數在線視頻網站都會用到302,原因很簡單,視頻網站流量一般較大,都會用到CDN,區別只在于是用自建CDN還是商業CDN。而由于302的重定向語義(再重復一遍,302的語義廣泛的被誤用,在使用302的時候,我們很可能應該使用303或307,但后面都不再糾結這一點),可以與CDN中的調度很好的結合起來。

我們來看一個例子,打開一個網易視頻播放頁面,抓一下包,找到302狀態的那個url。例如:

http://flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4

我們把它復制到瀏覽器地址欄中,會發現地址欄迅速的變為了另外一個url,這個Url是不定的,有可能為:

http://14.18.140.83/f6c00af500000000-1408987545-236096587/data6/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4

用curl工具會更清楚的看到整個過程:

curl -I "http://flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -LHTTP/1.1 302 Moved Temporarily Server: nginx Date: Mon, 25 Aug 2014 14:49:43 GMT Content-Type: text/html Content-Length: 154 Connection: keep-alive NG: CCN-SW-1-5L2 X-Mod-Name: GSLB/3.1.0 Location: http://119.134.254.9/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 HTTP/1.1 302 Moved Temporarily Server: nginx Date: Mon, 25 Aug 2014 14:49:41 GMT Content-Type: text/html Content-Length: 154 Connection: keep-alive X-Mod-Name: Mvod-Server/4.3.3 Location: http://119.134.254.7/cc89fdac00000000-1408983581-2095617481/data4/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 NG: CHN-SW-1-3Y1 HTTP/1.1 200 OK Server: nginx Date: Mon, 25 Aug 2014 14:49:41 GMT Content-Type: video/mp4 Content-Length: 3706468 Last-Modified: Mon, 25 Aug 2014 00:23:50 GMT Connection: keep-alive Cache-Control: no-cache ETag: "53fa8216-388e64" NG: CHN-SW-1-3g6 X-Mod-Name: Mvod-Server/4.3.3 Accept-Ranges: bytes

可以看到,這中間經歷了兩次302。

先暫時將這個例子放在一邊,再來說說另一個重要的術語:proxy.我們通常會戲稱,某些領導是302類型的,某些領導是proxy類型的。302類型的領導,一件事情經過他的手,會迅速的轉給他人,而proxy類型的領導則會參與到事情中來,甚至把事情全部做完。

回到上面的例子,如果訪問一個url中途會有多個302,那如果需要用Nginx設計一個proxy,來隱藏掉中間所有的這些302,該怎么做呢?

1.原始Proxy

我們知道,Nginx本身就是一個優秀的代理服務器。因此,首先我們來架設一個Nginx正向代理,服務器IP為192.168.109.128(我的一個測試虛擬機)。

初始配置簡化如下:

server {    listen 80;    location / {        rewrite_by_lua '            ngx.exec("/proxy-to" .. ngx.var.request_uri)        ';    }    location ~ /proxy-to/([^/]+)(.*) {        proxy_pass http://$1$2$is_args$query_string;    }}

實現的功能是,當使用

http://192.168.109.128/xxxxxx

訪問該代理時,會proxy到xxxxxx所代表的真實服務器。

測試結果如下:

curl -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -LHTTP/1.1 302 Moved Temporarily Server: nginx/1.4.6 Date: Mon, 25 Aug 2014 14:50:54 GMT Content-Type: text/html Content-Length: 154 Connection: keep-alive NG: CCN-SW-1-5L2 X-Mod-Name: GSLB/3.1.0 Location: http://183.61.140.24/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 HTTP/1.1 302 Moved Temporarily Server: nginx Date: Mon, 25 Aug 2014 14:50:55 GMT Content-Type: text/html Content-Length: 154 Connection: keep-alive X-Mod-Name: Mvod-Server/4.3.3 Location: http://183.61.140.20/540966e500000000-1408983655-236096587/data1/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 NG: CHN-ZJ-4-3M4 HTTP/1.1 200 OK Server: nginx Date: Mon, 25 Aug 2014 14:50:55 GMT Content-Type: video/mp4 Content-Length: 3706468 Last-Modified: Mon, 25 Aug 2014 00:31:03 GMT Connection: keep-alive Cache-Control: no-cache ETag: "53fa83c7-388e64" NG: CHN-ZJ-4-3M4 X-Mod-Name: Mvod-Server/4.3.3 Accept-Ranges: bytes

可見,雖然使用proxy,但過程與原始訪問沒有什么區別。訪問過程為,當訪問

http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4

時,Nginx會將該請求proxy到

http://flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4

而后者馬上就會返回一個302,所以Nginx作為proxy,將該302傳回到客戶端,客戶端重新發起請求,進而重復之前的多次302.這里說明一個問題,一旦Nginx的proxy的后端返回302后,客戶端即與Nginx這個proxy脫離關系了,Nginx無法起到完整的代理的作用。

2. 第1次修改

將配置文件修改為:

server {    listen 80;    location / {        rewrite_by_lua '            ngx.exec("/proxy-to" .. ngx.var.request_uri)        ';    }    location ~ /proxy-to/([^/]+)(.*) {        proxy_pass http://$1$2$is_args$query_string;        error_page 302 = @error_page_302;    }    location @error_page_302 {        rewrite_by_lua '            local _, _, upstream_http_location = string.find(ngx.var.upstream_http_location, "^http:/(.*)$")            ngx.header["zzzz"] = "/proxy-to" .. upstream_http_location            ngx.exec("/proxy-to" .. upstream_http_location);        ';    }}

與上面的區別在于,使用了一個error_page,目的是當發現proxy的后端返回302時,則用這個302的目的location繼續proxy,而不是直接返回給客戶端。并且這個邏輯里面包含著遞歸的意思,一路跟蹤302,直到最終返回200的那個地址。測試結果如下:

curl -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -LHTTP/1.1 302 Moved Temporarily Server: nginx/1.4.6 Date: Mon, 25 Aug 2014 15:01:17 GMT Content-Type: text/html Content-Length: 154 Connection: keep-alive NG: CCN-SW-1-5L2 X-Mod-Name: GSLB/3.1.0 Location: http://183.61.140.24/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 HTTP/1.1 302 Moved Temporarily Server: nginx Date: Mon, 25 Aug 2014 15:01:17 GMT Content-Type: text/html Content-Length: 154 Connection: keep-alive X-Mod-Name: Mvod-Server/4.3.3 Location: http://183.61.140.20/a90a952900000000-1408984277-236096587/data1/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 NG: CHN-ZJ-4-3M4 HTTP/1.1 200 OK Server: nginx Date: Mon, 25 Aug 2014 15:01:17 GMT Content-Type: video/mp4 Content-Length: 3706468 Last-Modified: Mon, 25 Aug 2014 00:31:03 GMT Connection: keep-alive Cache-Control: no-cache ETag: "53fa83c7-388e64" NG: CHN-ZJ-4-3M4 X-Mod-Name: Mvod-Server/4.3.3 Accept-Ranges: bytes

可見,本次修改仍然沒有成功!

為什么呢?分析一下,我們在@error_page_302這個location里已經加了一個頭部打印語句,可是在測試中,該頭部并沒有打出來,可見流程并沒有進入到@error_page_302這個location。

原因在于

error_page 302 = @error_page_302;

error_page默認是本次處理的返回碼。作為proxy,本次處理,只要轉發上游服務器的響應成功,應該狀態碼都是200.即,我們真正需要檢查的,是proxy的后端服務器返回的狀態碼,而不是proxy本身返回的狀態碼。查一下Nginx的wiki,proxy_intercept_errors指令正是干這個的:

Syntax: proxy_intercept_errors on | off;Default:  proxy_intercept_errors off;Context:  http, server, locationDetermines whether proxied responses with codes greater than or equal to 300 should be passed to a client or be redirected to nginx for processing with the error_page directive.

3. 第二次修改

server {    listen 80;    proxy_intercept_errors on;    location / {        rewrite_by_lua '            ngx.exec("/proxy-to" .. ngx.var.request_uri)        ';    }    location ~ /proxy-to/([^/]+)(.*) {        proxy_pass http://$1$2$is_args$query_string;        error_page 302 = @error_page_302;    }    location @error_page_302 {        rewrite_by_lua '            local _, _, upstream_http_location = string.find(ngx.var.upstream_http_location, "^http:/(.*)$")            ngx.header["zzzz"] = "/proxy-to" .. upstream_http_location            ngx.exec("/proxy-to" .. upstream_http_location);        ';    }}

與上一次修改相比,區別僅僅在于增加了一個proxy_intercept_errors指令。測試結果如下:

curl -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L HTTP/1.1 302 Moved TemporarilyServer: nginx/1.4.6Date: Mon, 25 Aug 2014 15:05:54 GMTContent-Type: text/htmlContent-Length: 160Connection: keep-alivezzzz: /proxy-to/183.61.140.24/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4

這次更神奇了,直接返回一個302狀態完事,也不繼續跳轉了。

問題出在,雖然第一次302,請求成功的進入到@error_page_302,但后續的error_page指令卻沒起作用。也就是說,error_page只檢查了第一次后端返回的狀態碼,而沒有繼續檢查后續的后端狀態碼。

查一下資料,這個時候,另一個指令 recursive_error_pages就派上用場了。

4. 第3次修改

server {    listen 80;    proxy_intercept_errors on;    recursive_error_pages on;    location / {        rewrite_by_lua '            ngx.exec("/proxy-to" .. ngx.var.request_uri)        ';    }    location ~ /proxy-to/([^/]+)(.*) {        proxy_pass http://$1$2$is_args$query_string;        error_page 302 = @error_page_302;    }    location @error_page_302 {        rewrite_by_lua '            local _, _, upstream_http_location = string.find(ngx.var.upstream_http_location, "^http:/(.*)$")            ngx.header["zzzz"] = "/proxy-to" .. upstream_http_location            ngx.exec("/proxy-to" .. upstream_http_location);        ';    }}

與上一次相比,僅僅增加了recursive_error_pages on這條指令。測試結果如下:

curl -I "http://192.168.109.128/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4" -L HTTP/1.1 200 OK Server: nginx/1.4.6 Date: Mon, 25 Aug 2014 15:09:04 GMT Content-Type: video/mp4 Content-Length: 3706468 Connection: keep-alive zzzz: /proxy-to/14.18.140.83/f48bad0100000000-1408984745-236096587/data6/flv.bn.netease.com/tvmrepo/2014/8/5/P/EA3I1J05P/SD/EA3I1J05P-mobile.mp4 Last-Modified: Mon, 25 Aug 2014 00:21:07 GMT Cache-Control: no-cache ETag: "53fa8173-388e64" NG: CHN-MM-4-3FE X-Mod-Name: Mvod-Server/4.3.3 Accept-Ranges: bytes

可見,Nginx終于成功的返回200了。此時,Nginx才真正起到了一個Proxy的功能,隱藏了一個請求原本的多個302鏈路,只返回客戶端一個最終結果。

5. 小結

綜上,通過proxy_pass、error_page、proxy_intercept_errors、recursive_error_pages這幾個指令的配合使用,可以向客戶端隱藏一條請求的跳轉細節,直接返回用戶一個狀態碼為200的最終結果。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到服務器教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久免费精品| 日韩大片免费观看视频播放| 欧美性猛交xxxx免费看漫画| 国产日韩精品视频| 亚洲自拍偷拍第一页| 91免费高清视频| 亚洲欧洲午夜一线一品| 欧美韩国理论所午夜片917电影| 欧美高清一级大片| 国产美女精品视频| 精品香蕉一区二区三区| 国产精品成熟老女人| 日韩男女性生活视频| 中国人与牲禽动交精品| 国产在线观看精品| 中文字幕少妇一区二区三区| 国产精品美女999| 亚洲欧美日韩中文视频| 欧美成人免费观看| 成人网在线观看| 国产男女猛烈无遮挡91| 欧美激情在线观看视频| 色综久久综合桃花网| 欧美国产日韩一区二区在线观看| 国产成人精品综合久久久| www.xxxx精品| 精品国产鲁一鲁一区二区张丽| 亚洲国产精品国自产拍av秋霞| 欧美日韩亚洲一区二区三区| 亚洲free嫩bbb| 久久久久久久亚洲精品| 2019最新中文字幕| 午夜剧场成人观在线视频免费观看| 国产成人精品优优av| 国产精品自拍小视频| 亚洲成色999久久网站| 国产精品日韩久久久久| 一区二区三区美女xx视频| 国产日韩欧美一二三区| 亚洲色图25p| 久久人人97超碰精品888| 久热精品视频在线观看| 成人亲热视频网站| 国产一区二区三区在线观看网站| 成人激情视频在线播放| 在线观看视频亚洲| 亚洲欧洲成视频免费观看| 亚洲自拍偷拍一区| 日韩在线视频线视频免费网站| 不卡伊人av在线播放| 欧美大片在线看| 国产91精品黑色丝袜高跟鞋| 97精品一区二区视频在线观看| 中文字幕亚洲综合久久筱田步美| 国产玖玖精品视频| 奇门遁甲1982国语版免费观看高清| 日韩av免费网站| 欧美国产极速在线| 欧美激情图片区| 国产精品自拍视频| 欧洲日韩成人av| 久久97精品久久久久久久不卡| 久久99热精品这里久久精品| 久久久久久久久久国产| 裸体女人亚洲精品一区| 91免费视频国产| 日本老师69xxx| 欧美猛男性生活免费| 亚洲男人天堂2023| 亚洲色图在线观看| 国产成人精品av| 精品国产成人在线| xxxxx成人.com| 国产一区二区成人| 欧洲亚洲在线视频| 国产性猛交xxxx免费看久久| 一本一本久久a久久精品牛牛影视| 亚洲日韩欧美视频| 亚洲精品成人av| 国产精品小说在线| 97热在线精品视频在线观看| 国语自产精品视频在线看| 亚洲人成自拍网站| 国产精品视频久久久| 欧美激情aaaa| 国精产品一区一区三区有限在线| 成人精品视频在线| 日韩av电影手机在线观看| 欧美在线激情网| 色噜噜狠狠狠综合曰曰曰| 国产一区二区三区日韩欧美| 久久人人爽人人爽人人片av高请| 欧美影院久久久| 成人国产精品一区二区| 最近2019年手机中文字幕| 亚洲电影第1页| 国内精品久久久久久影视8| 久久久久久久久久久91| 中文字幕亚洲第一| 热门国产精品亚洲第一区在线| 成人免费看黄网站| 亚洲一区美女视频在线观看免费| 日韩一区二区av| 最近日韩中文字幕中文| 琪琪第一精品导航| 欧美一级bbbbb性bbbb喷潮片| 国产精品亚洲一区二区三区| 精品成人在线视频| 日韩免费在线观看视频| 日韩亚洲欧美中文在线| 久久精品国产精品| 91精品在线一区| 亚洲欧美日韩另类| 91精品视频免费看| 午夜精品一区二区三区视频免费看| 亚洲成人黄色在线观看| 欧美最猛性xxxxx免费| 日韩av在线直播| 亚洲欧美国产日韩天堂区| 91精品国产高清自在线| 亚洲国产精品人久久电影| 夜夜嗨av色综合久久久综合网| 91精品国产一区| 亚洲国产日韩欧美在线图片| 亚洲3p在线观看| 高跟丝袜一区二区三区| 国产精品色视频| 国产97免费视| 国产精品国产亚洲伊人久久| 欧美日韩中国免费专区在线看| 亚洲欧美一区二区三区在线| 国产精品999| 欧美日韩一区二区精品| 亚洲精品国产精品久久清纯直播| 亚洲国产高潮在线观看| 欧美在线观看视频| 精品福利在线观看| 欧美另类极品videosbestfree| 51久久精品夜色国产麻豆| 色青青草原桃花久久综合| 日韩精品中文在线观看| 亚洲福利小视频| 色中色综合影院手机版在线观看| 一区二区三区四区在线观看视频| 久久69精品久久久久久国产越南| 日韩av一区在线观看| 亚洲成人1234| 亚洲少妇中文在线| 亚洲xxx自由成熟| 日韩中文av在线| 亚洲一区二区三区777| 欧美男插女视频| 91免费观看网站| 91av在线免费观看| 日韩大胆人体377p| 亚洲国产欧美久久| 亚洲综合精品伊人久久| 亚洲福利小视频| 中文字幕日韩有码| 色偷偷888欧美精品久久久| 亚洲成人久久电影| 中文字幕亚洲欧美一区二区三区| 亚洲a在线观看| 成人精品网站在线观看|