使用Nginx同时反代Jsdelivr和Gravatar

技术分享  ·  2026-01-15

由于网络环境原因,国内访问 Jsdelivr CDN 和 Gravatar 头像服务时常会遇到速度慢或无法访问的问题。通过 Nginx 反向代理,我们可以自建加速节点,有效提升资源加载速度和稳定性。本文将详细介绍如何配置 Nginx 同时反代这两个服务。

前提条件

  • 一台境外服务器(推荐延迟低于 100ms)
  • 已安装 Nginx(版本 ≥ 1.18)
  • 已配置 SSL 证书(Let's Encrypt 即可)
  • 域名(如 cdn.example.com

    替代方案:使用 Vercel 或 Netlify

    如果你没有国内访问性能比较好的服务器,那么你可以尝试使用 Vercel 和 Netlify 来反代。这两个平台提供全球 CDN 加速,且免费额度充足,非常适合作为个人项目的反向代理解决方案。
    可以使用我的开源项目:ZeinkCDN-Proxy,该项目提供了开箱即用的 Vercel 和 Netlify 部署配置,支持 Jsdelivr、Gravatar 等多个服务的反代,只需点击一键部署即可拥有自己的 CDN 加速节点。
    当然了如果你连折腾都嫌麻烦的话,可以使用我现成的:cdn.zeinklab.com

    配置步骤

  • 基础配置结构
    创建一个新的 Nginx 配置文件:

    sudo nano /etc/nginx/conf.d/reverse-proxy.conf
  • Jsdelivr 反代配置
    Jsdelivr 主要提供 npm、GitHub、WordPress 等 CDN 服务,我们分别配置不同路径:

    # npm 包反代
    location /npm/ {
      proxy_pass https://cdn.jsdelivr.net/npm/;
      proxy_set_header Host cdn.jsdelivr.net;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_cache_valid 200 304 12h;
    }
    # GitHub 文件反代
    location /gh/ {
      proxy_pass https://cdn.jsdelivr.net/gh/;
      proxy_set_header Host cdn.jsdelivr.net;
      proxy_cache_valid 200 304 12h;
    }
  • Gravatar 反代配置
    Gravatar 提供全球头像服务,配置如下:

    location /avatar/ {
      proxy_pass https://www.gravatar.com/avatar/;
      proxy_set_header Host www.gravatar.com;
      
      # 可选:指定默认头像和大小
      proxy_set_header Accept-Encoding "";
      sub_filter 'www.gravatar.com' 'cdn.example.com';
      sub_filter_once off;
      
      proxy_cache_valid 200 304 7d;
    }
  • 完整配置示例

    server {
      listen 80;
      listen 443 ssl http2;
      server_name cdn.example.com;
      
      # SSL 配置
      ssl_certificate /etc/letsencrypt/live/cdn.example.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/cdn.example.com/privkey.pem;
      
      # 安全 Headers
      add_header X-Content-Type-Options nosniff;
      add_header Cache-Control "public, immutable";
      
      # 日志
      access_log /var/log/nginx/cdn.access.log;
      error_log /var/log/nginx/cdn.error.log;
      
      # npm CDN 反代
      location /npm/ {
          proxy_pass https://cdn.jsdelivr.net/npm/;
          proxy_set_header Host cdn.jsdelivr.net;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          
          # 缓存配置
          proxy_cache cache_zone;
          proxy_cache_valid 200 304 12h;
          proxy_cache_valid 404 1m;
          proxy_cache_use_stale error timeout updating;
          
          # 超时设置
          proxy_connect_timeout 5s;
          proxy_send_timeout 10s;
          proxy_read_timeout 10s;
      }
      
      # GitHub CDN 反代
      location /gh/ {
          proxy_pass https://cdn.jsdelivr.net/gh/;
          proxy_set_header Host cdn.jsdelivr.net;
          proxy_cache cache_zone;
          proxy_cache_valid 200 304 12h;
      }
      
      # Gravatar 反代
      location /avatar/ {
          proxy_pass https://www.gravatar.com/avatar/;
          proxy_set_header Host www.gravatar.com;
          proxy_set_header User-Agent $http_user_agent;
          
          # 图片优化缓存
          proxy_cache cache_zone;
          proxy_cache_valid 200 304 7d;
          proxy_cache_valid 404 1h;
          
          # 可选:修改响应内容中的域名
          sub_filter 'www.gravatar.com' 'cdn.example.com';
          sub_filter_once off;
      }
      
      # 根路径重定向
      location / {
          return 301 https://your-main-site.com;
      }
    }
    # 缓存区域配置(添加到 http 块)
    http {
      # ... 其他配置
      
      proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=cache_zone:100m inactive=30d use_temp_path=off;
    }
  • 缓存目录创建

    sudo mkdir -p /var/cache/nginx
    sudo chown -R nginx:nginx /var/cache/nginx
  • 测试并重载配置

    # 测试配置语法
    sudo nginx -t
    # 重载 Nginx
    sudo systemctl reload nginx

    使用方式

    Jsdelivr 资源

    将原链接:

    https://cdn.jsdelivr.net/npm/vue@3.3.4/dist/vue.global.js

    替换为:

    https://cdn.example.com/npm/vue@3.3.4/dist/vue.global.js

    Gravatar 头像

    将原链接:

    https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50?s=200

    替换为:

    https://cdn.example.com/avatar/205e460b479e2e5b48aec07710c08d50?s=200

    高级优化

  • 缓存策略

    # 在 http 块中配置
    map $request_uri $cache_time {
      ~*\.(js|css|woff2)$  30d;
      ~*\.(jpg|png|gif)$   60d;
      default               12h;
    }
  • 防盗链配置

    location ~* \.(js|css|png|jpg)$ {
      valid_referers none blocked *.example.com example.com;
      if ($invalid_referer) {
          return 403;
      }
      # ... 其他代理配置
    }
  • HTTP/3 支持

    listen 443 quic reuseport;
    add_header Alt-Svc 'h3=":443"; ma=86400';

    缓存规则配置详解与推荐

    缓存层级结构设计

    建议采用多层级缓存策略,根据资源类型设置不同缓存时长:

    # 在 http 块中定义缓存区域(推荐配置)
    proxy_cache_path /var/cache/nginx/cdn levels=1:2 keys_zone=cdn_cache:200m inactive=60d max_size=50g use_temp_path=off;
    server {
      # ... 其他配置
      
      # npm 包缓存(版本固定,可长期缓存)
      location /npm/ {
          proxy_pass https://cdn.jsdelivr.net/npm/;
          proxy_cache cdn_cache;
          proxy_cache_key "$scheme$proxy_host$request_uri";
          proxy_cache_valid 200 301 302 365d;  # 成功响应缓存一年
          proxy_cache_valid 404 5m;            # 404错误仅缓存5分钟
          proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
          proxy_cache_background_update on;    # 后台更新过期缓存
          proxy_cache_lock on;                 # 防止缓存击穿
          
          # 添加缓存状态头(调试时用)
          add_header X-Cache-Status $upstream_cache_status;
          
          # 忽略源站缓存控制,强制缓存
          proxy_ignore_headers X-Accel-Expires Expires Cache-Control Set-Cookie;
          proxy_hide_header Set-Cookie;
      }
      
      # GitHub 文件缓存(可能更新,缓存时间适中)
      location /gh/ {
          proxy_pass https://cdn.jsdelivr.net/gh/;
          proxy_cache cdn_cache;
          proxy_cache_key "$scheme$proxy_host$request_uri";
          proxy_cache_valid 200 301 302 30d;   # GitHub文件可能更新,缓存30天
          proxy_cache_valid 404 10m;
          proxy_cache_use_stale error timeout updating;
          proxy_cache_background_update on;
      }
      
      # Gravatar 头像缓存(极长时间缓存)
      location /avatar/ {
          proxy_pass https://www.gravatar.com/avatar/;
          proxy_cache cdn_cache;
          proxy_cache_key "$scheme$proxy_host$request_uri";
          proxy_cache_valid 200 301 302 180d;  # 头像很少变化,缓存半年
          proxy_cache_valid 404 1d;
          proxy_cache_use_stale error timeout updating;
          
          # 对头像进行 WebP 转换(需要额外模块)
          # image_filter_buffer 10M;
          # image_filter_webp_quality 85;
      }
    }

    缓存键设计要点

  • proxy_cache_key 应包含足够区分度的信息,通常 $scheme$proxy_host$request_uri 已足够
  • 对于 Gravatar,建议将尺寸参数纳入缓存键,避免不同尺寸共用缓存导致图片变形
  • 使用 proxy_cache_lock 防止高并发时多个请求同时回源

    缓存清理与监控

    # 手动清理缓存(按URL模式)
    sudo find /var/cache/nginx/cdn -name "*vue@3.3.4*" -delete
    # 查看缓存统计
    sudo tail -f /var/log/nginx/cdn.access.log | grep -v "HIT"
    # 在Nginx配置中添加缓存监控接口
    location /purge_cache {
      allow 127.0.0.1;
      allow <你的IP>;
      deny all;
      
      proxy_cache_purge cdn_cache "$scheme$proxy_host$1";
    }

    配置文件深度优化

    性能优化配置

    # 在 http 块中
    http {
      # 启用 sendfile 零拷贝
      sendfile on;
      tcp_nopush on;
      tcp_nodelay on;
      
      # 调整缓冲区
      proxy_buffering on;
      proxy_buffer_size 4k;
      proxy_buffers 32 8k;
      proxy_busy_buffers_size 64k;
      
      # 开启 Gzip 压缩
      gzip on;
      gzip_comp_level 6;
      gzip_min_length 1000;
      gzip_proxied any;
      gzip_types
          text/plain
          text/css
          text/xml
          text/javascript
          application/json
          application/javascript
          application/xml+rss
          application/atom+xml
          image/svg+xml;
      
      # 连接复用
      upstream jsdelivr {
          server cdn.jsdelivr.net:443 max_fails=3 fail_timeout=30s;
          keepalive 32;
      }
      
      upstream gravatar {
          server www.gravatar.com:443 max_fails=3 fail_timeout=30s;
          keepalive 32;
      }
    }
    # 在 server 块中优化 location
    location /npm/ {
      proxy_pass https://jsdelivr/npm/;  # 使用 upstream
      proxy_http_version 1.1;            # 启用 HTTP/1.1
      proxy_set_header Connection "";     # 保持长连接
      # ... 其他配置
    }

    安全防护配置

    # 限制请求速率
    limit_req_zone $binary_remote_addr zone=cdn_limit:10m rate=10r/s;
    server {
      # ... 其他配置
      
      location /npm/ {
          limit_req zone=cdn_limit burst=20 nodelay;
          limit_req_status 429;
          
          # IP 白名单(可选)
          # allow 123.45.67.0/24;
          # deny all;
          
          # CORS 头
          add_header Access-Control-Allow-Origin *;
          add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS";
          add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
          
          if ($request_method = 'OPTIONS') {
              return 204;
          }
          
          # ... 其他代理配置
      }
    }
    # 隐藏 Nginx 版本信息
    server_tokens off;

    日志与监控优化

    # 自定义日志格式(包含缓存状态)
    log_format cdn_log '$remote_addr - $remote_user [$time_local] '
                     '"$request" $status $body_bytes_sent '
                     '"$http_referer" "$http_user_agent" '
                     'rt=$request_time uct="$upstream_cache_time" cs=$upstream_cache_status';
    access_log /var/log/nginx/cdn.access.log cdn_log;
    # 启用 Nginx 状态页面(需编译时包含 stub_status 模块)
    location /nginx_status {
      allow 127.0.0.1;
      allow <你的监控IP>;
      deny all;
      
      stub_status on;
      access_log off;
    }

    举一反三:扩展更多服务

    掌握了 Jsdelivr 和 Gravatar 的反代方法后,可以轻松扩展到其他常用服务:

  • 反代 Cloudflare CDNJS

    location /cdnjs/ {
      proxy_pass https://cdnjs.cloudflare.com/ajax/libs/;
      proxy_set_header Host cdnjs.cloudflare.com;
      proxy_cache cdn_cache;
      proxy_cache_valid 200 301 302 365d;  # CDNJS 资源极稳定
      proxy_cache_valid 404 5m;
      proxy_ignore_headers Cache-Control;
    }

    使用方式:将 https://cdnjs.cloudflare.com/ajax/libs/vue/3.3.4/vue.min.js 替换为 https://cdn.example.com/cdnjs/vue/3.3.4/vue.min.js

  • 反代 Google Fonts & AJAX

    # Google Fonts
    location ~ ^/fonts/(.*) {
      proxy_pass https://fonts.googleapis.com/$1;
      proxy_set_header Host fonts.googleapis.com;
      proxy_cache cdn_cache;
      proxy_cache_valid 200 30d;
    }
    # Google AJAX Libraries
    location ~ ^/ajax/(.*) {
      proxy_pass https://ajax.googleapis.com/ajax/libs/$1;
      proxy_set_header Host ajax.googleapis.com;
      proxy_cache cdn_cache;
      proxy_cache_valid 200 365d;
    }
  • 反代 Unsplash / GitHub Raw

    # Unsplash 图片
    location /unsplash/ {
      proxy_pass https://images.unsplash.com/;
      proxy_set_header Host images.unsplash.com;
      proxy_cache cdn_cache;
      proxy_cache_valid 200 60d;
    }
    # GitHub Raw 文件
    location ~ ^/github/([^/]+)/([^/]+)/(.*) {
      proxy_pass https://raw.githubusercontent.com/$1/$2/$3;
      proxy_set_header Host raw.githubusercontent.com;
      proxy_cache cdn_cache;
      proxy_cache_valid 200 301 302 7d;  # Raw 文件可能更新
      proxy_cache_valid 404 10m;
    }
  • 反代 npm 官方 registry

    # 注意:此配置仅用于加速下载,不适用于发布
    location /registry/ {
      proxy_pass https://registry.npmjs.org/;
      proxy_set_header Host registry.npmjs.org;
      proxy_cache cdn_cache;
      proxy_cache_valid 200 301 302 1h;  # npm 包元数据更新频繁
      proxy_cache_valid 404 1m;
      
      # 对于 tarball 文件使用更长的缓存
      location ~* \.tgz$ {
          proxy_cache_valid 200 30d;
      }
    }

    通用模式总结

    所有反代配置都遵循以下模式:

  • 路径匹配 :使用 location 精确匹配需要反代的路径
  • 上游地址 :proxy_pass 指向目标服务,注意末尾 / 的处理
  • Host 头:必须正确设置 proxy_set_header Host
  • 缓存策略:根据资源更新频率设置 proxy_cache_valid
  • 优化选项:按需添加压缩、CORS、防盗链等
    快速复制模板:

    location /服务名称/ {
      proxy_pass https://目标域名/路径/;
      proxy_set_header Host 目标域名;
      proxy_cache cdn_cache;
      proxy_cache_valid 200 301 302 缓存时长;
      add_header Access-Control-Allow-Origin *;  # 如需跨域
    }

    参考链接:

  • Nginx 官方文档
  • Jsdelivr 官网
  • Gravatar 官网
评论
泽客来宾. All Rights Reserved. Theme Jasmine by Kent Liao.