zjcqoo 6 ani în urmă
părinte
comite
f5f00aaf2f
6 a modificat fișierele cu 19 adăugiri și 12 ștergeri
  1. 9 6
      README.md
  2. 1 1
      api.conf
  3. 3 0
      lua/http-dec-req-hdr.lua
  4. 2 2
      lua/worker.lua
  5. 3 2
      nginx.conf
  6. 1 1
      upload.sh

+ 9 - 6
README.md

@@ -96,26 +96,29 @@ https://myhost.github.io     'my';
 参数和 nginx -s 相同。
 
 
-## 项目特点
+# 项目特点
 
 相比传统在线代理,本项目具有以下特点:
 
-### 服务端开销低
+## 服务端开销低
 
-传统在线代理的原理,基本都是在服务端替换 HTML/JS/CSS 等资源中的 URL。这不仅需要对内容做大量的分析和处理,还需对流量进行解压和再压缩,消耗大量的 CPU 资源。由于服务端的逻辑较为复杂,因此大多使用 Python/PHP 等自己实现。
+传统在线代理几乎都是在服务端替换 HTML/JS/CSS 等资源中的 URL。这不仅需要对内容做大量的分析和处理,还需对流量进行解压和再压缩,消耗大量 CPU 资源。并且由于逻辑较复杂,通常使用 Python/PHP 等编程语言自己实现。
 
-为降低服务端开销,本项目使用浏览器的一个黑科技 —— Service Worker。它能让 JS 拦截网页产生的请求,并能自定义返回内容,相当于在浏览器内部实现一个反向代理。这使得绝大部分的内容处理都可以在浏览器上完成,服务器只需纯粹的转发流量。
+为降低服务端开销,本项目使用浏览器的一个黑科技 —— Service Worker。它能让 JS 拦截网页产生的请求,并能自定义返回内容,相当于在浏览器内部实现一个反向代理。这使得绝大部分的内容处理都可以在浏览器上完成,服务器只需纯粹的转发流量。
 
 因此本项目服务端直接使用 nginx,并且转发过程不修改内容(只修改 HTTP 头),避免了内容处理产生的巨大开销。同时得益于 nginx 丰富的功能,很多常用需求无需重新造轮子,通过简单配置即可实现。并且无论性能还是稳定性,都远高于自己实现。
 
-### API 虚拟化
+## API 虚拟化
 
-传统在线代理大多只针对静态 URL 的替换,而忽视了动态加载 URL,以及和调用 URL 相关的网页 API。例如 a.com 反向代理 google.com,但页面中 JS 读取 `document.domain` 得到的仍是 a.com。这可能导致某些业务逻辑出现问题。
+传统在线代理大多只针对静态 URL 的替换,忽视了动态 URL 以及和 URL 相关的网页 API。例如 a.com 反向代理 google.com,但页面中 JS 读取 `document.domain` 得到的仍是 a.com。这可能导致某些业务逻辑出现问题。
 
 为缓解这个问题,本代理在页面头部注入一个 JS,用以重写绝大部分和 URL 相关的 API,使得页面中的 JS 获取到的仍是原始 URL:
 
 ![](https://raw.githubusercontent.com/EtherDream/jsproxy-localtest/temp/hook.png)
 
+对于有些无法重写的 API,例如 `location`,本代理会将代码中字面出现的 `location` 替换成 `__location`,从而将操作转移到自定义对象上。当然对于非字面的情况(例如 `this['lo' + 'cation']`),目前还无法处理。
+
+
 ### 界面和接口分离
 
 参见下文

+ 1 - 1
api.conf

@@ -9,7 +9,7 @@ proxy_set_header      Connection  $http_connection;
 
 set                   $_url       '';
 set                   $_ver       '';
-
+set                   $_ref       '';
 
 location = /preflight {
   internal;

+ 3 - 0
lua/http-dec-req-hdr.lua

@@ -21,6 +21,9 @@ for k, v in pairs(hdrs) do
   elseif k == 'ext' then
     extHdrs = require('cjson').decode(v)
   else
+    if k == 'referer' then
+      ngx.var._ref = v
+    end
     ngx.req.set_header(k, v)
   end
 

+ 2 - 2
lua/worker.lua

@@ -5,7 +5,7 @@ if ngx.worker.id() ~= 0 then
   return
 end
 
-local function getDevTraffic(dev)
+local function buildDevTrafficFn(dev)
   --       0     1       2    3    4    5     6          7
   -- eth0: bytes packets errs drop fifo frame compressed multicast
   --       bytes packets errs drop fifo colls carrier    compressed
@@ -45,7 +45,7 @@ if fileStat == nil then
 end
 
 local firstRun = true
-local getDevTraffic = getDevTraffic('eth0')
+local getDevTraffic = buildDevTrafficFn('eth0')
 
 
 local function updateTraffic()

+ 3 - 2
nginx.conf

@@ -29,11 +29,12 @@ http {
     '$time_iso8601	$_origin_id	$_ver	$remote_addr	'
     '$upstream_cache_status	$request_time	'
     '$request_length	$bytes_sent	'
-    '$request_method $_url	$status	$upstream_http_access_control_allow_origin	'
-    '$http_user_agent'
+    '$request_method	$_url	$status	$upstream_http_access_control_allow_origin	'
+    '$http_user_agent	$_ref'
   ;
   access_log              logs/proxy.log log_proxy buffer=64k flush=1s;
 
+  # 1MB = 8000key
   proxy_cache_path        cache
     levels=1:2
     keys_zone=my_cache:32m

+ 1 - 1
upload.sh

@@ -11,7 +11,7 @@ for v in ${NODE[@]}; do
   echo "$v upload ..."
 
   rsync . jsproxy@$v.$HOST:server \
-    -r -p \
+    -a \
     --exclude='nginx/cache/*' \
     --exclude='nginx/logs/*'