如何在 Next.js 中加载远程图片:两种方式详解(含防盗链解决方案)

How to Load Remote Images in Next.js: Two Approaches (with Anti-Hotlinking Proxy)

在构建基于 Next.js 的前端项目时,我们经常需要从外部加载图片。尤其是当图片来源于 CDN 或第三方站点时,有两个常用方式:

When building front-end applications with Next.js, it's common to load images from external sources such as CDNs or third-party domains. There are two main approaches to achieve this:


✅ 方法一:直接加载远程图片(通过 <Image src="https://...">

Approach 1: Load remote image directly with <Image src="https://...">

Next.js 的 <Image /> 组件默认会对图片做优化(压缩、webp 转换、lazy loading 等)。但如果你使用远程地址作为 src,必须在 next.config.js 中声明允许的域名

The <Image /> component in Next.js automatically optimizes images. However, when using an external URL as the src, you must explicitly allow that domain in your next.config.js.

📦 配置示例 / Config Example:

// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'cdn.example.com',
      },
    ],
  },
}

💡 不配置会报错:Invalid src prop 错误,阻止页面构建。

💡 Without this config, you'll get an Invalid src prop error and the page won't compile.


Approach 2: Use a Reverse Proxy API to Bypass Hotlinking Restrictions

当目标图片服务器设置了防盗链(如要求 Referer),你可以使用 Next.js 的 App Router 实现一个 /proxy 路由:

If the image host implements anti-hotlinking (e.g., checks for the Referer header), you can use App Router to implement a server-side proxy like /proxy.

📁 文件结构 / File Structure:

app/
├── proxy/
│   └── route.ts

✍️ 代码示例 / Proxy Code Example:

// app/proxy/route.ts
export async function GET(req: Request) {
  const { searchParams } = new URL(req.url)
  const targetUrl = searchParams.get('url')

  if (!targetUrl) {
    return new Response('Missing target url', { status: 400 })
  }

  const res = await fetch(targetUrl, {
    headers: {
      Referer: 'https://your-legit-site.com',
    },
  })

  return new Response(res.body, {
    status: res.status,
    headers: {
      'Content-Type': res.headers.get('Content-Type') || 'application/octet-stream',
      'Cache-Control': 'public, max-age=60',
    },
  })
}

🖼️ 前端使用方式 / Front-end Usage:

<Image
  src={`/proxy?url=${encodeURIComponent('https://cdn.example.com/image.jpg')}`}
  width={600}
  height={400}
  alt="图像"
  unoptimized // 避免重复优化
/>

✅ 因为 /proxy?... 是来自你自己的服务器,不需要在 next.config.js 配置 remotePatterns

✅ Since /proxy?... is a local server route, you don't need to whitelist it in next.config.js.


🎯 总结 / Summary

场景 / Scenario 是否需要配置 next.config.js 特点 / Notes
<Image src="https://cdn..." /> ✅ 是 需配置 remotePatterns 授权域名
<Image src="/proxy?url=..." /> ❌ 否 使用 App Router 中转,服务端 fetch,自动绕过防盗链限制

通过以上两种方式,你可以根据项目需求灵活选择最合适的图片加载策略,既兼顾安全与性能,又可规避被第三方图片防盗链机制阻挡的问题。

With these two approaches, you can flexibly choose the right image loading strategy in Next.js to balance security, performance, and third-party image restrictions.


posted @ 2025-06-07 04:53  PEAR2020  阅读(153)  评论(0)    收藏  举报