Next.js `next/image` 外部图片加载报错 `Invalid src prop` 修复:域名白名单配置
快速答案
- 结论:
next/image组件默认禁止加载外部域名图片,必须在next.config.js中显式配置白名单。 - 第一排查:检查报错信息中的
hostname(如example.com),确认是否已加入images.domains数组。 - 最小修复:在
next.config.js的images对象中添加domains: ['your-hostname.com'],然后重启开发服务器。 - 适用版本:Next.js 10+ 引入
next/image,domains配置在所有版本均有效;Next.js 12.3+ 推荐使用更灵活的remotePatterns。
它解决什么问题
当你在 Next.js 项目中使用 next/image 组件加载外部图片(例如来自 CDN、第三方 API 或用户上传服务的图片)时,会触发以下错误:
Error: Invalid src prop (https://example.com/image.jpg) on `next/image`, hostname "example.com" is not configured under images in your `next.config.js`
这是 Next.js 的安全机制——它强制要求开发者显式声明允许加载图片的外部域名,防止恶意图片源滥用服务器资源或执行 XSS 攻击。本文提供完整的配置方案和常见问题排查。
核心配置:domains 与 remotePatterns
基础配置(domains 数组)
在项目根目录的 next.config.js 中配置:
JAVASCRIPT// next.config.js const nextConfig = { images: { domains: [ 'example.com', 'cdn.example.com', 'images.another-domain.org', ], }, } module.exports = nextConfig
关键规则:
- 域名必须与图片 URL 中的
hostname完全一致(包括子域名)。例如https://images.example.com/pic.jpg需要添加'images.example.com',而不是'example.com'。 - 如果图片 URL 包含端口(如
https://example.com:3000/image.jpg),需添加'example.com:3000'。 - 修改配置后必须重启开发服务器(
npm run dev)或重新构建生产版本(npm run build && npm start)。
高级配置(remotePatterns,Next.js 12.3+)
remotePatterns 支持通配符匹配,适合管理大量子域名或动态域名:
JAVASCRIPT// next.config.js const nextConfig = { images: { remotePatterns: [ { protocol: 'https', hostname: '**.example.com', // 匹配任意深度的子域名 }, { protocol: 'https', hostname: 'cdn-*.provider.com', }, ], }, } module.exports = nextConfig
通配符规则:
*匹配单级域名段(如cdn-1.provider.com)**匹配任意深度(如a.b.example.com)
参数对比表
| 特性 | domains | remotePatterns |
|---|---|---|
| 引入版本 | Next.js 10 | Next.js 12.3+ |
| 通配符支持 | 不支持 | 支持 * 和 ** |
| 协议限制 | 无(默认 HTTPS) | 可指定 protocol |
| 端口匹配 | 需在域名后加 :port | 支持 port 字段 |
| 适用场景 | 少量固定域名 | 大量子域名或动态域名 |
常见报错与排查
报错 1:Invalid src prop — 域名未配置
错误信息:
Error: Invalid src prop (https://example.com/image.jpg) on `next/image`, hostname "example.com" is not configured under images in your `next.config.js`
解决步骤:
- 从报错中提取
hostname(如example.com)。 - 在
next.config.js的images.domains数组中添加该域名。 - 重启开发服务器。
报错 2:The requested resource isn't a valid image
错误信息:
Error: Image Optimization: The requested resource isn't a valid image.
可能原因:
- 图片 URL 指向非图片文件(如 HTML 页面、JSON 响应)。
- 图片源服务器返回了重定向(302)到非图片内容。
- 图片需要认证,但未提供凭证。
解决:在浏览器中直接访问该 URL,确认返回的是图片文件(检查 Content-Type 是否为 image/jpeg、image/png 等)。
报错 3:Connection timeout
错误信息:
Error: Image Optimization: Could not load image from remote URL. (Connection timeout)
解决:
- 检查 Next.js 服务器能否访问外部图片源(网络策略、防火墙)。
- 如果图片源响应慢,考虑使用
loader属性将优化任务委托给第三方服务(如 Cloudinary、Imgix)。
报错 4:Unsupported MIME type "text/html"
错误信息:
Error: Image Optimization: The image at "https://example.com/image.jpg" has an unsupported MIME type "text/html".
解决:图片 URL 返回了 HTML 内容。常见原因:
- URL 拼写错误。
- 需要登录或权限不足(返回了登录页面)。
- 图片源服务器配置了防盗链。
生产环境实践与注意事项
1. 动态管理域名白名单
如果图片源域名频繁变化,避免每次手动更新 next.config.js:
方案 A:使用环境变量
JAVASCRIPT// next.config.js const nextConfig = { images: { domains: process.env.ALLOWED_IMAGE_DOMAINS?.split(',') || [], }, }
方案 B:使用 remotePatterns 通配符
JAVASCRIPT// 允许所有 *.cdn.example.com 子域名 remotePatterns: [ { protocol: 'https', hostname: '*.cdn.example.com', }, ]
方案 C:自定义图片加载器 创建一个 API 路由作为图片代理,在代理层实现动态权限验证。
2. 安全加固
- 始终使用 HTTPS:避免中间人攻击。
- 后端验证:对图片 URL 进行额外的签名或哈希校验,防止恶意文件利用白名单域名。
- 输入清理:避免将用户输入直接作为
src属性值,进行严格的 URL 验证。
3. 性能优化
- CDN 缓存:将优化后的图片缓存到 CDN,减少服务器负载。
- 委托优化:使用
loader属性将图片优化任务交给专业服务(如 Cloudinary、Imgix),它们通常有更好的全球加速和格式转换能力。
常见问题 FAQ
Q: 配置了 domains 数组,但图片仍然无法加载,为什么?
A: 常见原因:
- 未重启服务器:修改
next.config.js后必须重启。 - 域名拼写错误:检查是否包含子域名。例如
https://images.example.com/pic.jpg需要'images.example.com'。 - 使用了
remotePatterns但配置错误:确保protocol和hostname正确。 - 图片 URL 包含端口:如
https://example.com:3000/image.jpg,需添加'example.com:3000'。
Q: 如何允许所有子域名?例如 *.example.com?
A: 使用 remotePatterns(Next.js 12.3+):
JAVASCRIPTremotePatterns: [ { protocol: 'https', hostname: '**.example.com', }, ]
** 匹配任意深度子域名(如 a.example.com、a.b.example.com)。
Q: 生产环境如何避免每次部署手动更新域名列表?
A: 三种方案:
- 环境变量:在
next.config.js中读取process.env.ALLOWED_IMAGE_DOMAINS。 - 通配符:如果域名有规律,使用
remotePatterns通配符。 - 自定义图片代理:通过 API 路由转发图片请求,在代理层动态控制权限。
相关深度解决方案
在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Next.js App Router Metadata 不更新?排查与解决方案。
在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Next.js Server Actions 请求体大小限制:配置、排查与生产实践。