跨域問題,解決之道

樑桂釗發表於2016-10-30

跨域問題,在日常開發過程中,是一個非常熟悉的名詞。今天的話題,結合我之前的專案場景,討論下《跨域問題,解決之道》。

原文地址:跨域問題,解決之道
部落格地址:blog.720ui.com/

跨域是什麼

跨域問題,是由於JavaScript出於安全方面的考慮,不允許跨域呼叫其他頁面的物件。換句話說,只有JavaScript存在跨域問題。

什麼情況下會出現跨域

不同源訪問,就算是跨域了喲。那什麼才算同源呢?一般來說,同源,即同一來源,包括主機名、協議和埠號。
例如,

跨域問題普遍麼

在現在前後端分離,微服務化之後,往往我們就存在許多不同的域名,這種情況下,就存在非常普遍的跨域問題。因此,跨域問題,在日常開發過程中,是一個非常熟悉的名詞。那麼,我們是如何去解決跨域問題呢?

解決之道

我們是如何去解決跨域問題呢?來吧,我們進入正題。

方案一,JSONP(廢棄)

很早很早之前,我有個專案曾經使用過JSONP處理跨域問題。簡單的理解,jsonp是帶有回撥函式callback的json,它是一個很棒的方案,可用於解決主流瀏覽器的跨域資料訪問的問題。但是,JSONP方案的侷限性在於,JSONP只能實現GET請求。隨著現在RESTful的興起,JSONP顯得力不從心了。因為,RESTful不僅有GET,還存在POST、PUT、PATCH、DELETE。

方案二,CORS(常用)

CORS 全稱為 Cross Origin Resource Sharing(跨域資源共享)。整個CORS通訊過程,都是瀏覽器自動完成,不需要使用者參與。對於開發者來說,CORS通訊與同源的AJAX通訊沒有差別,程式碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動新增一些附加的頭資訊,但使用者不會有感覺。因此,實現CORS通訊的關鍵是服務端。服務端只需新增相關響應頭資訊,即可實現客戶端發出 AJAX 跨域請求。

值得注意的是,瀏覽器必須先以 OPTIONS 請求方式傳送一個預請求,從而獲知伺服器端對跨源請求所支援 HTTP 方法。在確認伺服器允許該跨源請求的情況下,以實際的 HTTP 請求方法傳送那個真正的請求。

我們絕大多數專案採取這個方案,實現細節,不再擴充套件,如果有疑問,可以關注公眾號私信,或者評論留言喲。

但是,不幸的是,CORS不支援IE8、IE9,如果產品不再考慮相容IE低版本的話,可以忽略,但是如果產品需要相容目前國內還存在大量低版本的IE市場(百分之二十多),那麼這個需要慎重考慮咯。

附圖,留念。

跨域問題,解決之道

方案三,搭建中間轉發層(常用)

跨域問題的核心是什麼?不同源訪問。是啊,如果我們轉換成同源請求,就不存在這個問題啦。

因此,我們之前有個專案,通過搭建中間層,當然可以是java,也可以是node.js,通過將服務端的請求進行轉發,換句話說,就是dispatcher了一層,那麼前端請求的地址,就被轉發了,所以很好的解決跨域問題。

當然,如果對效能有考量的產品,就需要慎重選擇這個方案咯,因為多了一層中間轉發,不管是網路開銷,還是效能負載都是有一定的影響。

方案四,Nginx反向代理(常用)

首先,產品需要搭建一箇中轉nginx伺服器,用於轉發請求。當然,我們都是基於Nginx作為反向代理,所以當然是水到渠成。

那麼,Nginx的思路,就是通過Nginx解析URL地址的時候進行判斷,將請求轉發的具體的伺服器上。

說個思路,可能有點暈,我畫個圖,大家就理解了。

跨域問題,解決之道

當使用者請求xx.720ui.com/server1的時候,Nginx會將請求轉發給Server1這個伺服器上的具體應用,從而達到跨域的目的。

總結

跨域問題,在日常開發過程中,是一個非常熟悉的名詞。我們在開發過程中,或多或少都與它打過交道,因此,今天的話題,結合我之前的專案場景,以及JSONP、CORS、中間轉發層、Nginx反向代理四個方案進行總結,討論下《跨域問題,解決之道》。

(完)

更多精彩文章,盡在「服務端思維」微信公眾號!

跨域問題,解決之道

相關文章