Next.js中如何隐藏图片优化路由里的内部服务器IP?
解决Next.js next/image隐藏内网IP的方案
方案1:配置next.config.js远程源+自定义重写规则
这是最贴合Next.js图片优化机制的方案,核心是让客户端请求自定义路径,服务器内部转发到内网地址:
- 在
next.config.js中配置允许的远程图片源,并添加重写规则:
/** @type {import('next').NextConfig} */ const nextConfig = { images: { remotePatterns: [ { protocol: 'http', hostname: 'inner-server-ip', // 替换为你的内网IP }, ], // 自定义图片优化路由的前缀,避免和业务路径冲突 path: '/img-proxy', }, async rewrites() { return [ // 重写客户端的/img/*请求到内网服务器 { source: '/img/:path*', destination: 'http://inner-server-ip/img/:path*', }, // 关键:重写Next.js图片优化路由,把自定义路径转为内网地址 { source: '/img-proxy/_next/image?url=/img/:path*', destination: '/_next/image?url=http://inner-server-ip/img/:path*', has: [ { type: 'query', key: 'url', value: '/img/:path*', }, ], }, ]; }, }; module.exports = nextConfig;
- 组件中使用
next/image时,直接写相对路径(无需内网IP):
import Image from 'next/image'; export default function SSRPage() { return ( <Image src="/img/pic1.png" alt="示例图片" width={500} height={500} /> ); }
此时客户端看到的请求为/img-proxy/_next/image?url=/img/pic1.png,完全隐藏内网IP,服务器内部会自动转发到真实地址。
方案2:自定义图片代理API路由
如果重写规则不生效,可通过API路由完全接管图片请求:
- 创建代理路由(Pages Router版本:
pages/api/img-proxy.js):
import axios from 'axios'; import { promisify } from 'util'; import { pipeline } from 'stream'; const pipe = promisify(pipeline); export default async function handler(req, res) { const { path } = req.query; if (!path) return res.status(400).send('缺少图片路径'); const imgUrl = `http://inner-server-ip/img/${path.join('/')}`; try { const response = await axios({ url: imgUrl, method: 'GET', responseType: 'stream', }); res.setHeader('Content-Type', response.headers['content-type']); await pipe(response.data, res); } catch (err) { res.status(500).send('图片获取失败'); } }
App Router版本(app/api/img-proxy/route.js):
import { NextResponse } from 'next/server'; export async function GET(request) { const { searchParams } = new URL(request.url); const path = searchParams.get('path'); if (!path) return NextResponse.json({ error: '缺少图片路径' }, { status: 400 }); const imgUrl = `http://inner-server-ip/img/${path}`; try { const response = await fetch(imgUrl); return new NextResponse(response.body, { headers: { 'Content-Type': response.headers.get('content-type') }, }); } catch (err) { return NextResponse.json({ error: '图片获取失败' }, { status: 500 }); } }
- 组件中使用时关闭Next.js内置优化,指向代理路由:
import Image from 'next/image'; export default function SSRPage() { return ( <Image src={`/api/img-proxy?path=pic1.png`} alt="示例图片" width={500} height={500} unoptimized={true} // 关闭内置优化,用自定义代理处理 /> ); }
这种方式完全将内网IP隐藏在服务器端,客户端仅能看到域名下的API路径。
方案3:自定义next/image加载器
通过自定义加载逻辑,让客户端请求自定义路径,服务器再转发到内网:
- 定义加载器并配置重写规则:
// next.config.js const nextConfig = { async rewrites() { return [ { source: '/img/:filename', destination: 'http://inner-server-ip/img/:filename', has: [ { type: 'query', key: 'w' }, { type: 'query', key: 'q' }, ], }, ]; }, }; module.exports = nextConfig;
- 组件中使用自定义加载器:
import Image from 'next/image'; const customLoader = ({ src, width, quality }) => { return `/img/${src}?w=${width}&q=${quality || 75}`; }; export default function SSRPage() { return ( <Image loader={customLoader} src="pic1.png" // 仅传入文件名 alt="示例图片" width={500} height={500} /> ); }
客户端请求会是/img/pic1.png?w=500&q=75,内网IP完全被隐藏。
内容的提问来源于stack exchange,提问作者shahrooz bazrafshan
相关产品推荐
相关产品推荐

