同一個域名,能訪問不一樣服務器上的資源嗎?

其實這是一個很簡單的問題,答案固然是能夠的。
有時候,咱們在查看頁面的response headers的時候,會發現相同域名下,不一樣的域名有時候返回的server是不一樣的,也就是他們實際上是被部署在不一樣類型的服務器上。css

實現的原理其實也很簡單,不一樣類型的服務器都會提供反向代理功能。將知足必定條件的請求轉發到另外一臺服務器上便可。前端

最近工做的內容也涉及到相似的功能,前提是這樣的:咱們的產品是一個簡單的 CMS 產品,也就是每個客戶會擁有本身的獨立域名,使用咱們的網站產品,可是代碼是同一套部署。web

好比客戶主站的域名是:www.ag.com。咱們全部的產品能夠部署到用戶提供的一個子域名上: jobs.ag.com。這樣用戶只須要簡單的將jobs.ag.com放到他們的網站入口上就能夠了。瀏覽器

直到產品上線前一兩個月,獲得的需求是,客戶不但願有子域名的存在,但願域名可以統一。也就是說,用戶會在他們服務器上加設一層代理,全部的www.ag.com/jobs請求都會轉發到jobs.ag.com上。服務器

其實表面上看起來比較簡單,只是一層簡單的反向代理。可是細想,其實有不少問題。由於全部跟絕對路徑相關的都會出問題。框架

舉個例子:當用戶訪問:www.as.com/jobs/login點擊登陸之後,咱們會跳轉到/profile頁面。一旦加了這一層反向代理之後,實際上的跳轉頁面也會變成:www.as.com/profile。而後代碼就會走到客戶的服務器上致使 404 出現。網站

由於咱們實際上須要保證跳轉的頁面是:jobs.as.com/profile或者www.as.com/jobs/profile. 這樣才能保證,請求會到達 CMS 系統的服務器。代理

另一個現實是,咱們的CMS系統最開始就沒有考慮過根路徑會有變化這個可能性。也就是說在系統裏的跳轉都是至關隨意的。並且系統也比較老舊,前端同時存在jQuery和angularJS 的處理。code

因此要解決這個問題就得包含如下幾個方面:

  • 假設這個CMS站的prefixjobs。(其實須要讓不一樣的客戶能夠配置)
  • 確保全部的請求都支持prefix,也就是說:jobs.as.com/jobs/jobs.as.com可以同時處理。(這是爲了方便處理絕對路徑跳轉和充分支持客戶的反向代理)
  • 確保服務器端的頁面可以正確跳轉。
  • 確保 HTML/CSS 中的資源請求標籤(如:a, <script>, img)標籤可以正確處理。
  • 確保 angularJS 中的頁面跳轉可以正確處理。(ng-href
  • 確保 JS 中的跳轉可以正確處理。(window.location)

下面再來一個個解釋如何處理這些問題的

  1. 確保全部的請求都支持prefix
    這個其實很簡單,不一樣的web框架有不一樣的處理方案。簡單的說,就是服務器接收到request的時候判斷一下是否包含你定義的prefix(這裏是:jobs), 有的話去掉。server

    這樣就能保證全部jobs.ag.com/jobs/*的請求都會和jobs.ag.com/*相同。不一樣的框架也有不一樣的方案,好比修改routes層。只須要確保全部的頁面都能支持這個 prefix, 甚至須要包含靜態文件(js, css, images)。

  2. 確保服務器端的頁面可以正確跳轉。
    全部服務器端的內容其實都相對比較簡單。首先咱們可能須要直到服務器端跳轉的原理。
    當咱們請求 A頁面A頁面又跳轉到 B頁面。實際上發生的事情是:

    • 請求 A頁面的時候,A頁面會在 Response headers 裏添加一個字段叫作 location
    • 瀏覽器若是接收到 Response Headers裏的 location 字段,會從新發送一個 GET 請求到這個 URL

    並且大多數 web 框架其實都會封裝一個方法叫作 doRedirection(),而你全部作的其實也就是在 doRedirection() 這裏加上一層添加 prefix 在跟路徑的邏輯。

  3. 確保 HTML/CSS 中的資源請求標籤。
    這也是相對比較簡單的,體力活。
    在服務器端 response 以前截取到生成的 HTML,CSS 文件。窮舉出全部肯能包含web 請求的標籤,a,image 等等,而後判斷是否爲絕對路徑,是的話,加上 prefix.

  4. 確保 JS 中的跳轉可以正確處理。(window.location)

  5. 確保 angularJS 中的頁面跳轉可以正確處理。(ng-href)

相關文章
相關標籤/搜索