WebProxy - 网站转发代理

提到虚拟专用网络(下面简称为NPV),大家或多或少都使用过或者听说过。它能够通过专用网络,让我们访问原本访问不到的网络内容。一般大企业用NPV比较多,比如远程办公要连公司内网的时候,就会使用到它。

现在,我给大家介绍下开发的一套 WebProxy 软件。

从字面上来看,它是Web与Proxy的结合。实如其名,从这两个单词也能大概看出来它的用途:应用于Web网络的Proxy代理服务。

先来假设一个场景,让我们来看看它可以用在什么地方,来实际发现下它的用途和意义所在。

假如我有两台服务器,一台称之为A,连通外网,另一个称之为B,只存在于内网,但B服务器上面有很多网站服务。现在,我们想通过外网访问B服务器上的网站服务,一般是通过两种方法:1,把B暴露到外网,2,通过VPN连通B所在的内网然后访问。如果B不能连通外网,那么方案1显然就不能用了,需要用方案2,建立NPV专用网络。再假设一下,如果有100个人要访问B的服务,是不是要开通100个NPV账号?100个人每次都要先连VPN然后再访问,这些操作看起来就有些繁琐了。

现在我来推出另一个解决方案:WebProxy。

对于上面这个场景,我们可以在A服务器上搭建一个WebProxy服务,这样它自身可以发布到外网,同时它能访问B服务器上的资源,并提供“全量转发”功能,供外网用户访问B服务器的网站。

简单对比下NPV与WebProxy的功能与优缺点,来对两者有个更清晰的认识:

NPV:

优点:可以转发网站服务,也可以转发电脑应用、APP上的所有网络请求,转发速度快

缺点:每个用户要突破网络的时候,都要安装NPV软件、证书

WebProxy:

优点:只需要服务器开一个服务,所有用户都可以通过它突破网络限制进行访问

缺点:只应用于Web网络,不能应用于电脑软件、APP等软件,速度相对NPV来说较慢

从上面简单对比下,可以知道,NPV是单独开一个通道,供当前用户的当前设备(电脑、平板、手机等)突破网络限制,来访问无法直接访问的网络资源。而WebProxy,是通过一台连通外网与内网的中间服务器,打开一个公用通道,以突破网络限制,然后以网站服务的方式,提供对内网环境里的所有网站的转发服务。

上面说了WebProxy与NPV的对比,同时说到了WebProxy的代理转发功能。说到这里,可能会有小部分“懂点行”的软件开发人员会说,“nginx就能代理,要这个干嘛”。实际上,还真不是。

nginx代理无法完成“全量转发”网站的功能。为什么呢?第一,nginx代理网站,只能代理某个域名或IP,如果要代理多个,则需要配置多个域名或IP。第二,网站的运行基本都会依赖很多第三方网站的资源,比如cdn上的js、css文件,静态服务器上的图片、视频资源,第三方网站的网页嵌入,使用的第三方网站的接口,等等等等。上面的功能假如使用nginx代理暴露出来,那么实际上外网用户访问到的B服务器上的网站,很可能会因为各种第三方资源不存在而无法运行。

现在来说下,WebProxy的“全量转发”到底是怎么一回事。首先,“全量转发”分为两个层面,后端层面和前端层面,下面分别进行介绍。

“全量转发”后端层面:

一、网址转发服务

WebProxy后端会转换B服务器上的网站网址成为WebProxy自身的网址并提供服务,当用户访问被转换的网址时,WebProxy会先获取原网址的内容,然后经过内部的一系列处理后,再返回给外网用户。虽然中间有个WebProxy在转发,但在外网用户看来,跟直接访问原网站基本无异。

二、网址转换

后端会搜索获取到的所有 html、js、css 文件代码里的所有链接,并转换为WebProxy服务的网址,这些链接包括但不限于:

1. href、src、action、srcset、poster 等属性链接

2. css 代码里的 url() 链接

3. js 代码里的各种 import 导入的资源链接

4. 替换 js 代码里的所有 location.href 跳转

5. 替换 js 代码里的所有 navigate、location.assign、location.replace 跳转

6. 替换 js 代码里的所有 document.domain 域名

7. 往 html 代码里插入WebProxy前端运行时以支持前端网址转换

等等等等

“全量转发”前端层面:

一、拦截所有 Ajax 接口调用

主要拦截 XMLHttpRequest 接口调用并转换接口地址

二、拦截所有 fetch 接口调用

主要拦截 fetch 接口调用并转换接口地址

三、拦截所有 DOM 操作

1. 拦截所有元素插入操作并转换元素包含的链接,包括但不限于:

appendChild、insertBefore、replaceChild

replaceChildren、prepend、append、before、after

2. 拦截所有元素属性的赋值操作并转换属性包含的链接,包括但不限于:

href、src、srcset、poster、action、data、codebase

3. 拦截插入 html 代码的操作并转换包含的链接,包括但不限于:

insertAdjacentHTML

4. 拦截 html 代码写入文档的操作并转换包含的链接,包括但不限于:

document.write、document.writeln

Element.prototype.innerHTML

Element.prototype.outerHTML

四、拦截所有页面跳转操作

拦截网址跳转函数并转换包含的链接,包括但不限于:

window.open、history.go、window.navigate

location.assign、location.replace、location.href

pushState、replaceState

技术探讨先大概说到这里,具体的实现还是比较困难的,会遇到很多问题,不过多数也基本解决了。

现在来简单说下使用体验。个人使用上来说,基本的网站转发功能已经具备了,高级的网站转发,还有些欠缺的部分,后续也会继续更新维护。

普通的官网类型的网站,比如某些大学、某些公司的官网,基本都被WebProxy的“全量转发”拿捏了。另外,世界上最大的搜索引擎网站,也早都可以被代理了,现在,某中文搜索引擎,也可以在WebProxy下正常转发访问。

好虽好,不过欠缺的地方也是有的。比如各大视频网站,为了VIP视频的保护,本身就做了超多的加密,在动态的 js 代码里面做了各种各样的处理,导致这些视频网站上的视频还不能被WebProxy转发访问。这个目前不好处理,后续也会继续尝试处理。

总体来说,虽然目前WebProxy还处于起步阶段,但对于普通的展示型阅读型网站来说,可以满足基本的转发代理服务了。它目前的定位不是一整套解决方案,而是一个技术探讨型的软件。

目前WebProxy还不成熟,不过技术方面应该还是有值得参考的地方的。里面涉及网站多个方面的知识,后端、前端,请求头、响应头、http和https协议,静态文件、动态接口,网络视频传输,Ajax和fetch接口调用,DOM底层操作,网页跳转操作,网址编码、解码,等等等等。里面涉及的每个知识点,都跟网站运行息息相关。

最后,放上 github 的源码地址 https://github.com/LiebeU/WebProxy,开源贡献给大家,有想要使用的,或者想参与开发维护的,也可以联系。有相关需求,觉得需要做出一套产品的,也欢迎咨询。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
smiley-http-proxy-servlet是一个基于Java的代理服务器,可以用于转发请求并修改响应。要创建Proxy Servlet并修改cookie,您可以按照以下步骤进行: 1. 创建一个新的Java类并继承ProxyServlet类。 2. 重写doFilter方法,在方法中获取请求的cookie并进行修改,然后将请求转发给目标服务器。 3. 重写getProxyHost和getProxyPort方法,指定目标服务器的主机和端口。 4. 在web.xml文件中配置Servlet映射,使得请求能够正确地被代理Servlet处理。 下面是一个简单的示例代码,演示如何创建一个Proxy Servlet并修改cookie: ``` public class MyProxyServlet extends ProxyServlet { @Override protected void doFilter(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 获取请求的cookie Cookie[] cookies = servletRequest.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("myCookie")) { // 修改cookie cookie.setValue("newCookieValue"); servletResponse.addCookie(cookie); } } } // 转发请求给目标服务器 super.doFilter(servletRequest, servletResponse, filterChain); } @Override protected String getProxyHost(HttpServletRequest servletRequest) { // 指定目标服务器的主机 return "mytargetserver.com"; } @Override protected int getProxyPort(HttpServletRequest servletRequest) { // 指定目标服务器的端口 return 80; } } ``` 在web.xml文件中添加以下配置: ``` <servlet> <servlet-name>MyProxyServlet</servlet-name> <servlet-class>com.example.MyProxyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyProxyServlet</servlet-name> <url-pattern>/proxy/*</url-pattern> </servlet-mapping> ``` 以上示例代码仅供参考,具体实现需要根据您的具体需求进行调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值