一、搭建環(huán)境工作中經(jīng)常遇到需要在前端訪問(wèn)第三方平臺(tái)接口的情況,前端直接訪問(wèn)會(huì)遇到跨域、http 禁止調(diào)用 https 等問(wèn)題,故需要在后臺(tái)通過(guò) Nginx 進(jìn)行反向代理。隨著第三方平臺(tái)的增加,反向代理配置文件越來(lái)越復(fù)雜,因此筆者在考慮通過(guò)參數(shù)傳遞目標(biāo)地址實(shí)現(xiàn)動(dòng)態(tài)反向代理,本文將詳細(xì)介紹實(shí)現(xiàn)過(guò)程。
方案一:
通過(guò) query 參數(shù)攜帶反向代理目標(biāo)地址到 nginx,nginx 通過(guò)$arg_variable
獲取到代理地址,進(jìn)而通過(guò)proxy_pass
進(jìn)行反向代理。
方案二:
通過(guò) sub url 傳遞反向代理目標(biāo)地址到 nginx,nginx 通過(guò)正則匹配獲取到代理地址,進(jìn)而通過(guò)proxy_pass
進(jìn)行反向代理。
方案對(duì)比:
在實(shí)現(xiàn)的過(guò)程中,發(fā)現(xiàn)方案一存在以下問(wèn)題:
//
編碼成了/
;因此,筆者最終選擇了通過(guò)方案二來(lái)實(shí)現(xiàn),詳細(xì)的實(shí)現(xiàn)過(guò)程見(jiàn)下文。
三、實(shí)現(xiàn)過(guò)程配置 DNS 解析服務(wù)器:因?yàn)?code>proxy_pass使用變量時(shí)無(wú)法正確解析域名,因此需要手動(dòng)指定 DNS 解析服務(wù)器;
location /_proxy/ {
# 配置 DNS 服務(wù)器,proxy_pass 采用變量時(shí)需要指定
resolver 114.114.114.114 valid=3600s;
}
獲取代理地址:通過(guò)正則表達(dá)式獲取代理目標(biāo)地址,以 https://127.0.0.1/_proxy/https://api.github.com/search/users?q=test 為例;
location /_proxy/ {
# 配置 DNS 服務(wù)器,proxy_pass 采用變量時(shí)需要指定
resolver 114.114.114.114 valid=3600s;
# 通過(guò)正則截取路由中的 sub url
if ($request_uri ~* "/_proxy/(.*)") {
set $proxy_url $1;
}
}
進(jìn)行反向代理:通過(guò)正則獲取代理地址中的主機(jī)地址,并通過(guò)proxy_pass
進(jìn)行反向代理;
location /_proxy/ {
# 配置 DNS 服務(wù)器,proxy_pass 采用變量時(shí)需要指定
resolver 114.114.114.114 valid=3600s;
# 通過(guò)正則截取路由中的 sub url
if ($request_uri ~* "/_proxy/(.*)") {
set $proxy_url $1;
}
# 解析請(qǐng)求地址,并進(jìn)行反向代理
set $is_matched 0;
if ($proxy_url ~* "^(http|ws)(s?):\/\/?([a-zA-Z0-9\-\.]+:?\d*)([^\?]*)") {
set $is_matched 1;
set $proxy_protocol http$2;
set $proxy_host $3;
set $proxy_uri $4;
set $proxy_url $proxy_protocol://$proxy_host$proxy_uri;
proxy_pass $proxy_url$is_args$args;
}
}
注:proxy_pass 通過(guò)變量指定地址時(shí),不會(huì)將 query 參數(shù)傳遞給目標(biāo)地址,因此需要通過(guò)
$is_args$args
手動(dòng)傳遞 query 參數(shù)。
WebSocket 支持:根據(jù)$http_upgrade
的值實(shí)現(xiàn)動(dòng)態(tài)升級(jí) WebSocket 連接;
# map 指令根據(jù)客戶端請(qǐng)求頭中 $http_upgrade 的值構(gòu)建 $connection_upgrade 的值;如果 $http_upgrade 沒(méi)有匹配,默認(rèn)值為 upgrade,如果 $http_upgrade 配置空字符串,值為 close
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
location /_proxy/ {
# 配置 DNS 服務(wù)器,proxy_pass 采用變量時(shí)需要指定
resolver 114.114.114.114 valid=3600s;
# 通過(guò)正則截取路由中的 sub url
if ($request_uri ~* "/_proxy/(.*)") {
set $proxy_url $1;
}
# 解析請(qǐng)求地址,并進(jìn)行反向代理
set $is_matched 0;
if ($proxy_url ~* "^(http|ws)(s?):\/\/?([a-zA-Z0-9\-\.]+:?\d*)([^\?]*)") {
set $is_matched 1;
set $proxy_protocol http$2;
set $proxy_host $3;
set $proxy_uri $4;
set $proxy_url $proxy_protocol://$proxy_host$proxy_uri;
proxy_pass $proxy_url$is_args$args;
}
# 請(qǐng)求服務(wù)器升級(jí)協(xié)議為 WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# 設(shè)置讀寫(xiě)超時(shí)時(shí)間,默認(rèn) 60s 無(wú)數(shù)據(jù)連接將會(huì)斷開(kāi)
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
反向代理優(yōu)化:通過(guò)添加部分請(qǐng)求頭對(duì)反向代理進(jìn)行優(yōu)化;
# map 指令根據(jù)客戶端請(qǐng)求頭中 $http_upgrade 的值構(gòu)建 $connection_upgrade 的值;如果 $http_upgrade 沒(méi)有匹配,默認(rèn)值為 upgrade,如果 $http_upgrade 配置空字符串,值為 close
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
location /_proxy/ {
# 配置 DNS 服務(wù)器,proxy_pass 采用變量時(shí)需要指定
resolver 114.114.114.114 valid=3600s;
# 通過(guò)正則截取路由中的 sub url
if ($request_uri ~* "/_proxy/(.*)") {
set $proxy_url $1;
}
# 解析請(qǐng)求地址,并進(jìn)行反向代理
set $is_matched 0;
if ($proxy_url ~* "^(http|ws)(s?):\/\/?([a-zA-Z0-9\-\.]+:?\d*)([^\?]*)") {
set $is_matched 1;
set $proxy_protocol http$2;
set $proxy_host $3;
set $proxy_uri $4;
set $proxy_url $proxy_protocol://$proxy_host$proxy_uri;
proxy_pass $proxy_url$is_args$args;
}
# 請(qǐng)求服務(wù)器升級(jí)協(xié)議為 WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# 設(shè)置讀寫(xiě)超時(shí)時(shí)間,默認(rèn) 60s 無(wú)數(shù)據(jù)連接將會(huì)斷開(kāi)
proxy_read_timeout 300s;
proxy_send_timeout 300s;
# Host 主機(jī)名,為了避免目標(biāo)服務(wù)做限制此處采用目標(biāo)地址的 Host
proxy_set_header Host $proxy_host;
# X-Real-IP 將真實(shí)訪問(wèn)者的遠(yuǎn)端 IP 地址轉(zhuǎn)發(fā)給代理服務(wù)器
proxy_set_header X-Real-IP $remote_addr;
# X-Forwarded-For 標(biāo)記客戶端通過(guò)代理連接到服務(wù)器的源 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# X-Forwarded-Host 標(biāo)記客戶端通過(guò)代理連接到服務(wù)器的原始主機(jī)
proxy_set_header X-Forwarded-Host $host:$server_port;
# X-Forwarded-Server 代理服務(wù)器的主機(jī)名
proxy_set_header X-Forwarded-Server $host;
# X-Forwarded-Port 定義客戶端請(qǐng)求的原始端口
proxy_set_header X-Forwarded-Port $server_port;
# X-Forwarded-Proto 標(biāo)記客戶端通過(guò)代理連接到服務(wù)器的協(xié)議
proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
}
異常處理:對(duì)不合法的代理地址進(jìn)行提示;
# map 指令根據(jù)客戶端請(qǐng)求頭中 $http_upgrade 的值構(gòu)建 $connection_upgrade 的值;如果 $http_upgrade 沒(méi)有匹配,默認(rèn)值為 upgrade,如果 $http_upgrade 配置空字符串,值為 close
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
location /_proxy/ {
# 配置 DNS 服務(wù)器,proxy_pass 采用變量時(shí)需要指定
resolver 114.114.114.114 valid=3600s;
# 通過(guò)正則截取路由中的 sub url
if ($request_uri ~* "/_proxy/(.*)") {
set $proxy_url $1;
}
# 解析請(qǐng)求地址,并進(jìn)行反向代理
set $is_matched 0;
if ($proxy_url ~* "^(http|ws)(s?):\/\/?([a-zA-Z0-9\-\.]+:?\d*)([^\?]*)") {
set $is_matched 1;
set $proxy_protocol http$2;
set $proxy_host $3;
set $proxy_uri $4;
set $proxy_url $proxy_protocol://$proxy_host$proxy_uri;
proxy_pass $proxy_url$is_args$args;
}
# 請(qǐng)求服務(wù)器升級(jí)協(xié)議為 WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# 設(shè)置讀寫(xiě)超時(shí)時(shí)間,默認(rèn) 60s 無(wú)數(shù)據(jù)連接將會(huì)斷開(kāi)
proxy_read_timeout 300s;
proxy_send_timeout 300s;
# Host 主機(jī)名,為了避免目標(biāo)服務(wù)做限制此處采用目標(biāo)地址的 Host
proxy_set_header Host $proxy_host;
# X-Real-IP 將真實(shí)訪問(wèn)者的遠(yuǎn)端 IP 地址轉(zhuǎn)發(fā)給代理服務(wù)器
proxy_set_header X-Real-IP $remote_addr;
# X-Forwarded-For 標(biāo)記客戶端通過(guò)代理連接到服務(wù)器的源 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# X-Forwarded-Host 標(biāo)記客戶端通過(guò)代理連接到服務(wù)器的原始主機(jī)
proxy_set_header X-Forwarded-Host $host:$server_port;
# X-Forwarded-Server 代理服務(wù)器的主機(jī)名
proxy_set_header X-Forwarded-Server $host;
# X-Forwarded-Port 定義客戶端請(qǐng)求的原始端口
proxy_set_header X-Forwarded-Port $server_port;
# X-Forwarded-Proto 標(biāo)記客戶端通過(guò)代理連接到服務(wù)器的協(xié)議
proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
# 如果目標(biāo)地址為非 http、https、ws、wss 請(qǐng)求,提示錯(cuò)誤信息
default_type application/json;
if ($is_matched = 0) {
return 200 '{"code": 404, "message": "The proxy url is invalid!", "proxy_url": $proxy_url}';
}
# 調(diào)試輸出
# return 200 '{"code": 200, "proxy_url": $proxy_url$is_args$args, "proxy_host": $proxy_host, "request_uri": $request_uri}';
}
# map 指令根據(jù)客戶端請(qǐng)求頭中 $http_upgrade 的值構(gòu)建 $connection_upgrade 的值;如果 $http_upgrade 沒(méi)有匹配,默認(rèn)值為 upgrade,如果 $http_upgrade 配置空字符串,值為 close
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
location /_proxy/ {
# 配置 DNS 服務(wù)器,proxy_pass 采用變量時(shí)需要指定
resolver 114.114.114.114 valid=3600s;
# 通過(guò)正則截取路由中的 sub url
if ($request_uri ~* "/_proxy/(.*)") {
set $proxy_url $1;
}
# 解析請(qǐng)求地址,并進(jìn)行反向代理
set $is_matched 0;
if ($proxy_url ~* "^(http|ws)(s?):\/\/?([a-zA-Z0-9\-\.]+:?\d*)([^\?]*)") {
set $is_matched 1;
set $proxy_protocol http$2;
set $proxy_host $3;
set $proxy_uri $4;
set $proxy_url $proxy_protocol://$proxy_host$proxy_uri;
proxy_pass $proxy_url$is_args$args;
}
# 請(qǐng)求服務(wù)器升級(jí)協(xié)議為 WebSocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# 設(shè)置讀寫(xiě)超時(shí)時(shí)間,默認(rèn) 60s 無(wú)數(shù)據(jù)連接將會(huì)斷開(kāi)
proxy_read_timeout 300s;
proxy_send_timeout 300s;
# Host 主機(jī)名,為了避免目標(biāo)服務(wù)做限制此處采用目標(biāo)地址的 Host
proxy_set_header Host $proxy_host;
# X-Real-IP 將真實(shí)訪問(wèn)者的遠(yuǎn)端 IP 地址轉(zhuǎn)發(fā)給代理服務(wù)器
proxy_set_header X-Real-IP $remote_addr;
# X-Forwarded-For 標(biāo)記客戶端通過(guò)代理連接到服務(wù)器的源 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# X-Forwarded-Host 標(biāo)記客戶端通過(guò)代理連接到服務(wù)器的原始主機(jī)
proxy_set_header X-Forwarded-Host $host:$server_port;
# X-Forwarded-Server 代理服務(wù)器的主機(jī)名
proxy_set_header X-Forwarded-Server $host;
# X-Forwarded-Port 定義客戶端請(qǐng)求的原始端口
proxy_set_header X-Forwarded-Port $server_port;
# X-Forwarded-Proto 標(biāo)記客戶端通過(guò)代理連接到服務(wù)器的協(xié)議
proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
# 如果目標(biāo)地址為非 http、https、ws、wss 請(qǐng)求,提示錯(cuò)誤信息
default_type application/json;
if ($is_matched = 0) {
return 200 '{"code": 404, "message": "The proxy url is invalid!", "proxy_url": $proxy_url}';
}
# 調(diào)試輸出
# return 200 '{"code": 200, "proxy_url": $proxy_url$is_args$args, "proxy_host": $proxy_host, "request_uri": $request_uri}';
}
參考鏈接:
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)頁(yè)名稱:Nginx動(dòng)態(tài)反向代理(2022/11/12)-創(chuàng)新互聯(lián)
本文來(lái)源:http://aaarwkj.com/article46/jdehg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、響應(yīng)式網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)、域名注冊(cè)、服務(wù)器托管、網(wǎng)站營(yíng)銷(xiāo)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容