如何在 Next.js 中加载远程图片:两种方式详解(含防盗链解决方案)
<h2 id="how-to-load-remote-images-in-nextjs-two-approaches-with-anti-hotlinking-proxy">How to Load Remote Images in Next.js: Two Approaches (with Anti-Hotlinking Proxy)</h2><p>在构建基于 Next.js 的前端项目时,我们经常需要从外部加载图片。尤其是当图片来源于 CDN 或第三方站点时,有两个常用方式:</p>
<p>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:</p>
<hr>
<h2 id="-方法一直接加载远程图片通过-image-srchttps">✅ 方法一:直接加载远程图片(通过 <code><Image src="https://..."></code>)</h2>
<h3 id="approach-1-load-remote-image-directly-with-image-srchttps">Approach 1: Load remote image directly with <code><Image src="https://..."></code></h3>
<p>Next.js 的 <code><Image /></code> 组件默认会对图片做优化(压缩、webp 转换、lazy loading 等)。但如果你使用远程地址作为 <code>src</code>,必须在 <code>next.config.js</code> 中声明<strong>允许的域名</strong>。</p>
<p>The <code><Image /></code> component in Next.js automatically optimizes images. However, when using an external URL as the <code>src</code>, you <strong>must explicitly allow that domain</strong> in your <code>next.config.js</code>.</p>
<p>📦 配置示例 / Config Example:</p>
<pre><code class="language-js">// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'cdn.example.com',
},
],
},
}
</code></pre>
<p>💡 不配置会报错:<code>Invalid src prop</code> 错误,阻止页面构建。</p>
<p>💡 Without this config, you'll get an <code>Invalid src prop</code> error and the page won't compile.</p>
<hr>
<h2 id="-方法二使用服务端反向代理proxy-api解决-hotlink-问题">✅ 方法二:使用服务端反向代理(Proxy API)解决 Hotlink 问题</h2>
<h3 id="approach-2-use-a-reverse-proxy-api-to-bypass-hotlinking-restrictions">Approach 2: Use a Reverse Proxy API to Bypass Hotlinking Restrictions</h3>
<p>当目标图片服务器设置了防盗链(如要求 Referer),你可以使用 Next.js 的 App Router 实现一个 <code>/proxy</code> 路由:</p>
<p>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 <code>/proxy</code>.</p>
<h4 id="-文件结构--file-structure">📁 文件结构 / File Structure:</h4>
<pre><code>app/
├── proxy/
│ └── route.ts
</code></pre>
<h4 id="️-代码示例--proxy-code-example">✍️ 代码示例 / Proxy Code Example:</h4>
<pre><code class="language-ts">// 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',
},
})
}
</code></pre>
<h4 id="️-前端使用方式--front-end-usage">🖼️ 前端使用方式 / Front-end Usage:</h4>
<pre><code class="language-tsx"><Image
src={`/proxy?url=${encodeURIComponent('https://cdn.example.com/image.jpg')}`}
width={600}
height={400}
alt="图像"
unoptimized // 避免重复优化
/>
</code></pre>
<blockquote>
<p>✅ 因为 <code>/proxy?...</code> 是来自你自己的服务器,<strong>不需要在 next.config.js 配置 remotePatterns</strong>!</p>
</blockquote>
<blockquote>
<p>✅ Since <code>/proxy?...</code> is a local server route, you <strong>don't need to whitelist it in <code>next.config.js</code></strong>.</p>
</blockquote>
<hr>
<h2 id="-总结--summary">🎯 总结 / Summary</h2>
<table>
<thead>
<tr>
<th>场景 / Scenario</th>
<th>是否需要配置 next.config.js</th>
<th>特点 / Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><code><Image src="https://cdn..." /></code></td>
<td>✅ 是</td>
<td>需配置 <code>remotePatterns</code> 授权域名</td>
</tr>
<tr>
<td><code><Image src="/proxy?url=..." /></code></td>
<td>❌ 否</td>
<td>使用 App Router 中转,服务端 fetch,自动绕过防盗链限制</td>
</tr>
</tbody>
</table>
<hr>
<p>通过以上两种方式,你可以根据项目需求灵活选择最合适的图片加载策略,既兼顾安全与性能,又可规避被第三方图片防盗链机制阻挡的问题。</p>
<p>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.</p>
<hr><br><br>
来源:https://www.cnblogs.com/sabertobih/p/18915173
頁:
[1]