nest搭建图片代理

333 阅读2分钟

NestJS 前端图片防盗链解决方案:后端代理 vs 其他方式全对比

在开发中,尤其是内容平台聚合、爬虫展示类应用,常会遇到「图片防盗链」问题,掘金、微博、知乎等平台的图片不能直接使用 <img> 标签访问。

本文将从多个维度分析,详细对比不同的应对方式,并最终推荐一个最低成本、最高兼容性、最易实现的解决方案。

应用场景

以掘金图片为例:

<img src="https://p3-juejin.byteimg.com/origin/abc.jpg" />

会出现:

  • 图片无法加载
  • 控制台报错:403 Forbidden

掘金通过 Referer 判断是否为盗链请求。

之前的效果是图片加载不出来,浏览器打开也是403

image.png

image.png


常见解决方案对比

方案是否可行优点缺点
直接使用图片 URL❌ 不可行简单直接被防盗链策略拦截(403)
<img referrerpolicy>❌ 掘金无效某些站可用掘金这类 Referer 校验平台无效
Base64 转换⚠️ 可行但不推荐不怕跨域请求成本高、性能差
第三方代理如 images.weserv.nl⚠️ 勉强可用零配置、简单替代不稳定、失效率高、转发慢
✅ 自建 NestJS 代理服务✅ 推荐方案灵活、稳定、可控、Referer 可伪造需少量后端开发时间

推荐方案:NestJS 后端图片代理

通过 NestJS 提供一个统一接口,后端伪造 Referer,再将图片返回给前端。

首先询问claude,我们使用的是nest搭建一个图片代理接口,我们对代码的目录设计就有个大概,当然前端也是要配合的,要将其md文档进行正则替换,减少不必要的修改,造成大量时间成本花费

image.png

✅ 实现效果

<img src="/proxy/img?url=https%3A%2F%2Fp3-juejin.byteimg.com%2Forigin%2Fabc.jpg" />

NestJS 后端负责转发请求,并伪装 Referer: https://juejin.cn/,完美绕过防盗链。


🔧 NestJS 实现步骤

1. 创建代理控制器

@Controller('proxy')
export class ProxyController {
  @Get('img')
  async proxyImg(@Query('url') url: string, @Res() res: Response) {
    if (!url?.startsWith('http')) {
      return res.status(400).send('Invalid URL');
    }

    try {
      const response = await axios.get(url, {
        responseType: 'arraybuffer',
        headers: { Referer: 'https://juejin.cn/' },
      });
      res.setHeader('Content-Type', response.headers['content-type'] || 'image/jpeg');
      res.send(response.data);
    } catch (e) {
      res.status(500).send('图片加载失败');
    }
  }
}

2. 注册模块

@Module({ controllers: [ProxyController] })
export class ProxyModule {}

AppModule 中引入:

imports: [ProxyModule]

🧩 前端正则替换方案

function replaceImageSrc(content) {
  return content.replace(/<img\s+[^>]*src="(https?://[^"]+)"[^>]*>/g, (match, url) => {
    return match.replace(url, `/proxy/img?url=${encodeURIComponent(url)}`);
  });
}

在 Vue 中使用:

<div v-html="replaceImageSrc(rawHtml)" />

💡 Bonus:是否需要缓存?

是否需要缓存场景
❌ 不需要少量访问,静态页面、内容展示为主
✅ 建议加频繁重复请求、内容量大、SEO 优化

可以使用内存 Map、文件缓存、Redis 等方案。

最终效果成功显示出来

image.png


✅ 总结

方案兼容性性能实现难度推荐指数
直接链接❌ 差★★★
第三方图片代理⚠️ 一般★★⚠️
Base64❌ 差⭐⭐
✅ NestJS 代理✅ 高★★★⭐⭐✅✅✅

如果你想要低成本、可控、稳定又灵活的解决方案,NestJS 后端代理配合正则替换,是目前前后端协作的最优解。