目录

代理服务器突破限制,实现下载

警告
2023-12-26 代码失效,相关服务有 https://github.com/hunshcn/gh-proxy ,请前往该仓库使用,简单快捷。
介绍
可以使用 nginx 进行 GitHub 等相关网站进行更好的代理下载,但是其余网站进行同样的配置太耗时间,因此通过 Node.js 实现一个简单的代理服务器用于加速下载。

原理

本文将介绍如何使用 Node.js 实现一个简单的代理服务器,用于加速文件下载。代理服务器的原理是将客户端发起的下载请求代理到目标服务器,并将目标服务器的响应返回给客户端。通过代理服务器,我们可以实现以下加速原理:

  1. 缓存优化:代理服务器可以设置适当的 HTTP 缓存头,将目标服务器的响应缓存到本地,避免重复下载相同的文件。这样可以大幅度减少请求的响应时间,提高文件下载速度。

  2. 并发请求:代理服务器可以同时发起多个并发请求来下载文件的不同部分,这样可以加快整个下载过程。并发请求通常会利用浏览器或网络的并行性,从而提高下载速度。

  3. 压缩传输:代理服务器可以对目标服务器的响应进行压缩,减少传输数据的大小。压缩传输可以降低网络传输时间,进一步加快文件下载速度。

为什么要做这个

文件下载是 Web 应用中常见的需求,但对于大文件或网络条件较差的情况,文件下载速度可能会变得很慢。为了提供更好的用户体验和加速文件下载过程,我们可以使用代理服务器来优化下载过程,从而减少用户等待时间。

有什么好处

通过使用代理服务器实现文件下载加速,我们可以获得以下好处:

  1. 快速下载:使用代理服务器可以减少响应时间和传输数据量,从而加快文件下载速度,提供更快的下载体验。
  2. 节省带宽:通过压缩传输和缓存优化,代理服务器可以节省带宽使用,减少服务器负载,降低运营成本。
  3. 网络稳定性:对于跨国下载或目标服务器不稳定的情况,代理服务器可以提供更稳定的下载连接,减少下载中断和失败的情况。
  4. 绕过网络限制:用户可以绕过一些网络封锁和限制,从而实现下载一些因为网络封锁而无法直接下载的内容。使用代理服务器可以在一定程度上解决这个问题,因为代理服务器会将请求转发到目标服务器,并将目标服务器的响应返回给用户。通过这种方式,用户可以间接地获取到那些受限制的内容。

如何做

步骤 1:安装 Node.js 和相关模块

首先,确保你的计算机上已经安装了 Node.js。然后,在一个空白目录下创建一个新的 Node.js 项目,并在项目目录中初始化一个 package.json 文件:

1
npm init -y

接着,安装需要的依赖模块 node-fetchhttp

1
npm install node-fetch http --save

步骤 2:编写代理服务器代码

创建一个名为 proxy-server.js 的文件,并将以下代码粘贴到该文件中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import http from 'http'; 
import fetch from 'node-fetch';

const PORT = 3000;

async function handleRequest(request, response) {
  try {
    const newUrl = request.url.replace("/https://", "https://");
    const upstreamResponse = await fetch(newUrl);

    // Copy headers from the upstream response to the server response
    response.writeHead(upstreamResponse.status, upstreamResponse.headers);

    upstreamResponse.body.pipe(response);
  } catch (error) {
    console.error("Error: ", error.message);
    response.writeHead(500, { 'Content-Type': 'text/plain' });
    response.end('Internal Server Error');
  }
}

http.createServer(handleRequest).listen(PORT, () => {
  console.log(`Proxy server listening on port ${PORT}...`);
});
  • 上面是简单配置,其余需求请自行添加,比如添加并发请求

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
    import http from 'http';
    import fetch from 'node-fetch';
    import { parse } from 'url';
    
    const PORT = 3000;
    
    async function handleRequest(request, response) {
      try {
        const newUrl = request.url.replace("/https://", "https://");
        const parsedUrl = parse(newUrl); // 解析 URL
    
        // 定义要同时发起的并发请求
        const requests = [
          fetch(newUrl),
          fetch(newUrl),
          fetch(newUrl),
          fetch(newUrl),
          fetch(newUrl),
          fetch(newUrl),
          // 添加更多的并发请求...
        ];
    
        const responses = await Promise.all(requests); // 发起并等待所有请求完成
    
        // 将所有请求的响应合并到最终的响应中
        responses.forEach((upstreamResponse) => {
          response.writeHead(upstreamResponse.status, upstreamResponse.headers);
          upstreamResponse.body.pipe(response);
        });
      } catch (error) {
        console.error("Error: ", error.message);
        response.writeHead(500, { 'Content-Type': 'text/plain' });
        response.end('Internal Server Error');
      }
    }
    
    http.createServer(handleRequest).listen(PORT, () => {
      console.log(`Proxy server listening on port ${PORT}...`);
    });
    

步骤 3:运行代理服务器

在命令行中运行代理服务器:

1
node proxy-server.js

现在,代理服务器将会在本地监听端口 3000。任何发送到该端口的请求都将被代理并下载相应的文件。

步骤 4:使用 Nginx 反代,使用 SSL

使用 acme.sh 申请 SSL,然后使用 Nginx 反代即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
server {
    listen                  443 ssl http2;
    listen                  [::]:443 ssl http2;
    server_name             example2.com;

    # SSL
    ssl_certificate         /etc/nginx/ssl/example2.com/fullchain.cer;
    ssl_certificate_key     /etc/nginx/ssl/example2.com/example2.com.key;
    ssl_trusted_certificate /etc/nginx/ssl/example2.com/ca.cer;

    # security
    include                 nginxconfig.io/security.conf;

    # logging
    access_log              /var/log/nginx/access.log combined buffer=512k flush=1m;
    error_log               /var/log/nginx/error.log warn;

    # reverse proxy
    location / {
        proxy_pass            http://127.0.0.1:3000;
        proxy_set_header Host $host;
        include               nginxconfig.io/proxy.conf;
    }

    # additional config
    include nginxconfig.io/general.conf;
}

# HTTP redirect
server {
    listen      80;
    listen      [::]:80;
    server_name example2.com;

    location / {
        return 301 https://example2.com$request_uri;
    }
}

步骤 5:访问被封锁的内容

在浏览器或下载工具中,将下载链接的主机部分修改为代理服务器的地址,例如:

https://github.com/username/repository/archive/master.zip 替换为 https://example2.com/https://github.com/username/repository/archive/master.zip

这样,通过访问代理服务器地址来下载 GitHub 的内容,可以绕过一些网络封锁和限制。

Cloudflare Woker 实现

步骤 1:域名解析

将域名(比如自己的域名为:a.test.com)随便解析到一个 IP 上,不管它是否可用。打开 Cloudflare 的小云朵(Cloudflare 代理打开)。

步骤 2:创建 Worker 应用

前往 Workers 和 Pages,创建一个 worker 应用,然后将代码改为以下内容1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const newUrl = request.url.replace("https://a.test.com/https://", "https://")
  const response = await fetch(newUrl)

  // you may want to add caching headers here to improve performance
  // as well as handling errors if the upstream server is down
  return response
}

步骤 3:自定义域名

worker 应用的触发器,将自己的域名 a.test.com 添加到自定义域名。

步骤 4:添加路由

在自定义路由的下方,添加路由:a.test.com/*

步骤 5:访问被封锁的内容

在浏览器或下载工具中,将下载链接的主机部分修改为代理服务器的地址,例如:

https://github.com/username/repository/archive/master.zip 替换为 https://a.test.com/https://github.com/username/repository/archive/master.zip

总结

实现代理服务器成功实现了文件下载加速。通过并发请求等策略,实现了更快的下载体验,同时优化了网络带宽和服务器负载。代理服务器有效地突破了下载限制,是我们拥有了高效、便捷的文件下载服务。让我们可以减少网络封锁带来的影响,看到,学到更多的知识。


  1. 小猪佩奇. cfworker拉各种大文件一把梭[EB/OL]. [2023-07-22]. https://hostloc.com/thread-1187420-1-1.html↩︎