-
背景
用户需要通过前端HTML页面的noVNC(noVNC是什么?)客户端连接底层VNC Server服务端,为了防止VNC Server的IP暴露,因此需要做一层代理。正常情况下使用Nginx、Apache等都可以搞定,但是由于项目架构的一些问题,暂时不能再加一台反向代理服务器,所以决定写一个单独的模块实现反向代理的功能。
在网上和Github上找了一下,使用了HTTP-Proxy-Servlet,引入该依赖搭建一个Spring Boot项目。
-
搭建
-
引入代理的依赖
<dependency> <groupId>org.mitre.dsmiley.httpproxy</groupId> <artifactId>smiley-http-proxy-servlet</artifactId> <version>1.12</version> </dependency>
-
通过注册bean拦截指定URL路径进行自定义操作
@Configuration public class ProxyServletConfiguration { // 拦截所有请求交给下面的VNCProxyServlet去处理 private final static String SERVLET_URL = "/*"; @Bean public ServletRegistrationBean<VNCProxyServlet> servletServletRegistrationBean() { ServletRegistrationBean<VNCProxyServlet> servletRegistrationBean = new ServletRegistrationBean<>(new VNCProxyServlet(), SERVLET_URL); //设置网址以及参数 Map<String, String> params = ImmutableMap.of( "targetUri", "null", //这里写null是因为targetUri是在自定义的VNCProxyServlet类中动态传入的,而且这里必须要有值 ProxyServlet.P_LOG, "true", ProxyServlet.P_PRESERVEHOST,"true", ProxyServlet.P_PRESERVECOOKIES,"true" ); servletRegistrationBean.setInitParameters(params); return servletRegistrationBean; } }
这里遇到的坑:
刚开始其实是准备在已有的一个模块中加上这个代理功能,因为可以指定拦截的路径,比如只拦截请求路径为/proxy/*的,然后交给自定义的Servlet去代理,后来写好测试时,发现代理过去后代理目标主页一片空白,看了控制台的Network后,主页确实是返回200且加载正常,但是由主页发起的js、css和img等静态资源状态码都为404。
当时以为是代码的问题,后来发现静态资源都是相对路径的有问题,如果前端的静态资源是引入第三方的,比如从CDN中引入Vue.js则不会出现问题,都可以正常的被代理。既然状态码是404,那肯定是找不到这个资源,看了一下发现如果在静态资源的路径前加上指定拦截的路径