# Kuboard Proxy - Rebase

# 为什么要 Rebase

Rebase 是在使用反向代理的情况下,解决前端页面加载所依赖资源时如何计算资源路径的问题。

要完整显示一个前端页面,浏览器除了从服务器加载该页面本身的 html 文件之外,还需要加载一系列该文件引用的资源文件,甚至被引用资源文件引用的其他的资源文件。在使用代理的情况下,正常加载页面本身的 html 文件(即入口文件)通常不会出现问题,但是,被引用的资源文件则不一定能正确加载到。因为,代理服务器很有可能会改变页面所在的上下文。

导入 example 中导入的 Eureka 服务为例,直接通过域名的方式访问该服务的 URL 为:

http://cloud-eureka.example.demo.eip.work/ 您所使用的 URL 可能与这个不一样

访问该 URL 后,所得的 html 代码如下所示:

为了节省篇幅,下面只截取了一些代码片段。



 


 




 


 




<!doctype html>
<head>
  <base href="/">
  <meta charset="utf-8">
  <title>Eureka</title>
  <link rel="stylesheet" href="eureka/css/wro.css">
</head>
<body id="one">
...
    <li>
      <a href="/lastn">Last 1000 since startup</a>
    </li>
...
    <script type="text/javascript" src="eureka/js/wro.js" ></script>
...
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

上述代码中:

  • 第3行代码定义了文档的 base 路径 /,该文档应用的所有资源(如果以相对路径的方式引用)都将基于此 base 路径进行计算,例如:
    • 第6行的 eureka/css/wro.css,进行路径计算之后,结果是 http://cloud-eureka.example.demo.eip.work/eureka/css/wro.css
    • 第14行的 eureka/js/wro.js,进行路径计算之后,结果是 http://cloud-eureka.example.demo.eip.work/eureka/js/wro.j
  • / 开头的路径,仍然从根路径开始计算,例如:
    • 第11行的 /lastn,进行路径计算之后,结果是 http://cloud-eureka.example.demo.eip.work/lastn

但是,如果您使用 KuboardProxy 访问此页面时,页面的路径是 https://kuboard.demo.eip.work/proxy/http/example/web-example/:/80/,在这种情况下,如果代理响应的结果和上面的代码保持一致,以上述第6行代码为例,由于第三行 base 路径仍然为 /,则 eureka/css/wro.css,进行路径计算之后,结果是 http://cloud-eureka.example.demo.eip.work/eureka/css/wro.css;由于代理为 Web 应用增加了 /proxy/http/example/web-example/:/80/ 作为上下文,此时 http://cloud-eureka.example.demo.eip.work/eureka/css/wro.css 这样的 URL 是访问不到期望的资源的。以此类推,其他这种相对资源也都将不能正常加载。

如果使用 kubectl proxy 访问,页面路径是 http://localhost:8001/api/v1/namespaces/example/services/http:cloud-eureka:9200/proxy

对于这种情况,为了使网页能够正常工作,Kuboard Proxy、kubectl proxy 都对代理的响应结果做了 Rebase,即修改 base 的路径,修改 / 的路径。Rebase 之后,浏览器通过 Kuboard Proxy 实际获取到的 HTML 代码如下所示,这时,该网页所有依赖的资源就可以正常加载,网页也就可以正常工作了:



 


 




 


 




<!doctype html>
<head>
  <base href="/proxy/http/example/cloud-eureka/:/9200/">
  <meta charset="utf-8">
  <title>Eureka</title>
  <link rel="stylesheet" href="eureka/css/wro.css">
</head>
<body id="one">
...
    <li>
      <a href="/proxy/http/example/cloud-eureka/:/9200/lastn">Last 1000 since startup</a>
    </li>
...
    <script type="text/javascript" src="eureka/js/wro.js" ></script>
...
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# Kuboard Proxy 怎样做 Rebase

Kuboard Proxy 针对 text/html / application/javascript 这两种类型的响应内容做了如下形式的文本替换:

替换前 替换后 kubectl proxy
src="/ src="/proxy/http/example/web-example/:/80/ 替换
src=/ src=/proxy/http/example/web-example/:/80/ 替换
href="/ href="/proxy/http/example/web-example/:/80/ 替换
href=/ href=/proxy/http/example/web-example/:/80/ 替换
baseURL="/ baseURL="/proxy/http/example/web-example/:/80/ 不替换
baseURL=/ baseURL=/proxy/http/example/web-example/:/80/ 不替换
  • kubectl proxy 只替换了 text/html 类型响应中的 src="/src=/href="/href=/
  • Kuboard Proxy 额外处理了 application/javascript 类型的响应,并且替换了 baseURL="/、和 baseURL=/,以应对使用 axios (opens new window) 作为 http 库的前端网站,例如 导入 example 中导入的 web-example 服务的页面,在 Kuboard Proxy 中就可以正常通过 Restful 接口获取到动态数据,而如果通过 kubectl proxy,则获取不到的动态数据;

风险

由于对 text/html / application/javascript 这两种类型的响应做了简单的纯文本搜索和替换,不排除可能会发生不恰当替换的风险,例如:

  • html 页面中的出现了文本内容(不是 html 标签) src="/href=/ 等,该内容也将被替换掉;
  • 如果您通过 KuboardProxy 进行 Restful 接口调用,不存在此风险,因为 Restful 接口的响应类型是 application/json

# Kuboard Proxy 禁用 Rebase

在少数情况下,您可能需要禁用 Rebase:

禁用 Rebase 的步骤,请参考 KuboardProxy 代理配置

更新时间: 2020-02-27 23:35:35