Demo: (以 Google 为例,请用无痕浏览 /隐身模式打开,以免 Cookie 污染)
https://proxlet.now.sh/https://google.com
请温柔使用,我账户的免费额度是每天 5000 次请求
原理其实没什么技术含量:访问一个网站主请求的响应会被加上一个额外的 Cookie,值为其 URL 本身(类似于 Referer ),这样其域内的后续子请求因为带上了这个 Cookie 而能被服务端导向正确地址(一个显然的缺陷是,跨域请求都不能被反代,见下“已知的限制”)。重定向在服务端会被拦截处理。除此之外,对于响应不会有任何修改。
这样,每个请求都相互独立,于是就可以上 Serverless 了。我自己的实验中,Zeit Now (即 demo )是成功的。AWS Lambda 和 GCF 默认的 HTTP 网关都带路径的,后续请求不能用,绑定自定义域名我就没试了。
我的实现很 naïve,基于 Go 自带的 httputil.ReverseProxy,核心功能不过百行代码,请大佬们轻喷。这个项目的目标是展现只需要一个很小的切入点就可以实现简单无状态的任意网页反代,距离一个完善可用的实现还有很远的距离。
贴上代码: https://github.com/Contextualist/proxlet
或许我这个想法(即利用 Cookie 做反代)已经有更好的实现了,如果各位有见过,请不吝赐教。
已知的限制:
- 跨域请求都不能被反代,除非篡改响应正文里的链接,但是这就把问题引向了另一个复杂的方向。我相信在链接替换方面应该已经有成熟的方案了,我就不造轮了。
- Serverless 的提供商对请求和响应的大小会有限制:对于 Now 和 AWS Lambda 是 6MB,对于 GCF 是 10MB。