您當前的位置:首頁 > 舞蹈

利用 Nginx 反向代理解決跨域問題

作者:由 智障de剋星 發表于 舞蹈時間:2019-11-28

上篇 JSONP 的文章裡提到過利用 Nginx 也可以解決跨域問題。趁著自己以前沒有接觸過 Nginx,熟悉了一下,順帶寫了一個非常非常簡單的 demo 實驗下。

正向代理和反向代理

提到代理,肯定要說一下這兩個的區別。

舉個正向代理的例子:我打球累了走不動了,找看球的小朋友幫我去旁邊的商店買瓶水。商店老闆是不知道到底是誰需要喝水的,隱藏了客戶端。當然,小朋友可以告訴老闆就是那個打球像蔡徐坤的人要喝水。還有,VPN 就是正向代理。

反向代理的例子:我打球累了,找看球的小朋友要瓶水喝(當然我肯定會給錢的:D)。我不需要知道小朋友的水是從旁邊的商店還是兩公里外的超市買的。隱藏了服務端。還有,我們連好了 VPN 訪問谷歌的時候,瀏覽的那些頁面,我們是不會知道具體是哪臺伺服器的資源。

具體步驟

服務介面

既然請求,肯定需要先寫一個服務介面,我們用 node 起一個服務:

// index。js

const

http

=

require

‘http’

);

const

fs

=

require

‘fs’

);

const

url

=

require

‘url’

);

const

server

=

http

createServer

function

req

res

{

if

req

url

===

‘/favicon。ico’

{

return

}

const

parseUrl

=

url

parse

req

url

true

);

console

log

‘parseUrl’

parseUrl

pathname

if

parseUrl

pathname

===

‘/api/getList’

{

const

list

=

{

‘a’

1

‘b’

2

}

res

writeHead

200

{

‘content-Type’

‘text/html;charset=UTF-8’

})

res

end

JSON

stringify

list

))

}

else

{

res

write

`

port: 666

`

res

end

()

}

});

server

listen

666

function

()

{

console

log

‘server is starting on port 666’

);

});

我們來訪問一下,可以拿到資料了。

利用 Nginx 反向代理解決跨域問題

測試頁面

然後,我們寫一個簡單的 ajax 請求頁面。你可以本地用

http-server

啟動訪問下,可以發現請求跨域了:

<

html

>

<

head

>

<

title

><

/title>

<

/head>

<

body

>

<

button

onclick

=

“sendAjax()”

>

sendAjax

<

/button>

<

script

type

=

“text/javascript”

>

var

sendAjax

=

()

=>

{

var

xhr

=

new

XMLHttpRequest

();

xhr

open

‘GET’

‘http://localhost:666/api/getList’

true

);

xhr

send

();

xhr

onreadystatechange

=

function

e

{

if

xhr

readyState

==

4

&&

xhr

status

==

200

{

console

log

xhr

responseText

);

}

};

}

<

/script>

<

/body>

<

/html>

利用 Nginx 反向代理解決跨域問題

安裝 Nginx

這個時候,你可以透過設定響應頭來允許跨域。或者用 Nginx 來解決這個問題了。首先肯定需要安裝 Nginx。這個按照對應的平臺安裝就行了。

brew update

brew install nginx

nginx

nginx -s reload // 重啟

配置

然後我們配置一下代理,這個意思就是我們請求中有 api 這樣的就會代理到 http://127。0。0。1:666,所以我們只要訪問

http://

localhost:9999/api/getL

ist

這個不跨域的介面,然後就會由伺服器反向代理到 http://localhost:666/api/getList。

listen 9999;

server_name localhost;

#charset koi8-r;

#access_log logs/host。access。log main;

location / {

root html;

index index。html index。htm;

}

location /api/ {

proxy_pass http://127。0。0。1:666;

}

配置好之後我們需要重啟一下 Nginx 服務。注意一點,重啟時可能會報這麼一個錯誤:

nginx: [error] open() “/usr/local/var/run/nginx。pid” failed (2: No such file or directory)

這是

sudo nginx -s stop

這個命令會刪除 pid 檔案,可以執行

sudo nginx

重新新增這個檔案。

測試結果

這個時候,我們不用絕對地址了,我們把ajax請求裡面的介面換成相對地址:

// xhr。open(‘GET’, ‘http://localhost:666/api/getList’, true);

xhr。open(‘GET’, ‘/api/getList’, true);

利用 Nginx 反向代理解決跨域問題

美滋滋,這就不跨域了呢。

當然,還可以更加真實一點,我們隨便用一個域名測試一下。Nginx 重新配置下:

listen

80

server_name

yumingtest

#

charset

koi8

-

r

#

access_log

logs

/

host

access

log

main

location

/

{

root

html

index

index

html

index

htm

}

location

/

api

/

{

proxy_pass

http

//127。0。0。1:666;

}

然後在 hosts 檔案裡面新增這條:

127。0。0。1 yumingtest。com

,重啟下 Nginx。

利用 Nginx 反向代理解決跨域問題

這下是不是更加真實了。關於hosts 檔案的作用,就是我們輸入域名不是要需要經過DNS解析IP嘛,這個裡面就存了一些。首先自動從 Hosts 檔案中尋找對應的 IP 地址,一旦找到,系統會立即開啟對應網頁,如果沒有找到, 則系統再會將網址提交 DNS 域名解析伺服器進行 IP 地址的解析。

還有一個問題,關於 HTTP 502 狀態碼,我是把介面服務停了,於是就報 502了。

利用 Nginx 反向代理解決跨域問題

也不一定是網上說的什麼

連線超時 我們向伺服器傳送請求 由於伺服器當前連結太多,導致伺服器方面無法給於正常的響應,產生此類報錯

那樣。

(完)

2019。11。30 補充

上面 Hosts 檔案那裡說錯了,輸入域名後並不是先自動從 Hosts 檔案中尋找對應的 IP 地址。而是瀏覽器先從瀏覽器的dns快取中找,找不到再去 hosts檔案中找 :)

標簽: http  API  666  nginx  xhr