Caddy 實戰(九)- 設置頭信息實現跨域
在前端開發中,會通過 fetch
發起網絡請求獲取數據,然後再顯示到頁面上,這也就是我們常說的前後端分離。
但是受限於瀏覽器的同源策略, fetch
是不能跨域訪問的,這時候就需要我們設置服務端響應的頭信息,來達到跨域的目的,而 Caddy 的反向代理,天生就具備這個能力。
什麼是同源策略
同源策略是瀏覽器的一項非常重要的安全策略,它用於限制一個 origin 的文檔或者它加載的腳本如何能與另一個源的資源進行交互。它能幫助阻隔惡意文檔,減少可能被攻擊的媒介。
我們看下它的定義:
同源策略是指在 Web 瀏覽器中,允許某個網頁腳本訪問另一個網頁的數據,但前提是這兩個網頁必須有相同的 URI、主機名和端口號,一旦兩個網站滿足上述條件,這兩個網站就被認定爲具有相同來源
同源策略對 Web 應用程序具有特殊意義,因爲 Web 應用程序廣泛依賴於 HTTP cookie 來維持用戶會話,所以必須將不相關網站嚴格分隔,以防止丟失數據泄露。
頭信息設置
在 Caddy 的反向代理中,爲我們提供了兩個指令來設置請求頭和響應頭的信息,他們分別是 header_up 和 header_down,他們的指令設置規則如下所示:
reverse_proxy [<matcher>] [<upstreams...>] {
# backends
to <upstreams...>
...
# header manipulation
header_up [+|-]<field> [<value|regexp> [<replacement>]]
header_down [+|-]<field> [<value|regexp> [<replacement>]]
}
-
header_up
: 用於添加、移除和設置客戶端到上游主機(後端)的請求頭信息。也就是說利用它,可以修改客戶端請求的頭信息,然後再傳給上游後端服務。看到它後面的+|-
表達式了嗎?+
表示添加一個頭信息,-
表示移除一個頭信息,都沒有的時候表示設置一個頭信息。可以同時有多個header_up
。 -
header_down
: 和header_up
的作用一樣,只不過它是用於修改後端服務響應的頭信息,然後再傳給客戶端,方向正好是反的。
只介紹使用,可能會覺得有點繞,下面我們通過一個示例來看下就明白了,和我們平時設置頭信息差不多的。
https://example.com {
reverse_proxy /path http://localhost:54321 {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Port {server_port}
header_up X-Forwarded-Proto "http"
}
}
以上就是一個重新設置 Host、X-Real-IP 等請求頭的示例,通過 header_up
設置,一行設置一個,非常簡單。
這裏需要留意的是 {host}
這些佔位符,他們是 Caddy 預定義的,可以理解爲一個變量,可以在 Caddyfile 中使用,Nginx 也有類似的佔位符,只不過是以 $
開頭的。
實現跨域訪問
無法跨域的時候,瀏覽器會返回 403 的錯誤:No 'Access-Control-Allow-Origin' header is present on the requested resource,從這個我們就能看到需要設置 Access-Control-Allow-Origin
這個頭信息,而且是返回的響應頭信息,下面我們看下如何在 Caddy 中配置跨域訪問。
https://example.com {
reverse_proxy /path http://localhost:54321 {
header_up Host {http.reverse_proxy.upstream.hostport}
header_down Access-Control-Allow-Headers *
header_down Access-Control-Allow-Origin *
}
}
以上實現跨域的重點在於header_down
的設置,這裏的header_up
也一種比較好的安全措施,後端可以根據 Host 校驗請求是否合法。
以上設置後,就可以跨域訪問了,非常簡單。
小結
跨域只是頭信息設置的一種使用場景,其他還有很多,結合頭信息,可以自由發揮使用,從這個也可以發現,相比 Nginx,Caddy 還是比較輕的。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/HRlRK9ilSifXOJ7u7iSU9w