同一个域名,能访问不一样服务器上的资源吗?

其实这是一个很简单的问题,答案固然是能够的。
有时候,咱们在查看页面的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)

相关文章
相关标签/搜索