Next.js `next/image` 外部图片加载报错 `Invalid src prop` 修复:域名白名单配置

主题: nextjs-invalid-image-src-prop-fix更新于: 2026/7/7作者:AgentFactory 技术团队

快速答案

  • 结论next/image 组件默认禁止加载外部域名图片,必须在 next.config.js 中显式配置白名单。
  • 第一排查:检查报错信息中的 hostname(如 example.com),确认是否已加入 images.domains 数组。
  • 最小修复:在 next.config.jsimages 对象中添加 domains: ['your-hostname.com'],然后重启开发服务器。
  • 适用版本:Next.js 10+ 引入 next/imagedomains 配置在所有版本均有效;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 攻击。本文提供完整的配置方案和常见问题排查。

核心配置:domainsremotePatterns

基础配置(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

参数对比表

特性domainsremotePatterns
引入版本Next.js 10Next.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`

解决步骤

  1. 从报错中提取 hostname(如 example.com)。
  2. next.config.jsimages.domains 数组中添加该域名。
  3. 重启开发服务器。

报错 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/jpegimage/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: 常见原因:

  1. 未重启服务器:修改 next.config.js 后必须重启。
  2. 域名拼写错误:检查是否包含子域名。例如 https://images.example.com/pic.jpg 需要 'images.example.com'
  3. 使用了 remotePatterns 但配置错误:确保 protocolhostname 正确。
  4. 图片 URL 包含端口:如 https://example.com:3000/image.jpg,需添加 'example.com:3000'

Q: 如何允许所有子域名?例如 *.example.com

A: 使用 remotePatterns(Next.js 12.3+):

JAVASCRIPT
remotePatterns: [
  {
    protocol: 'https',
    hostname: '**.example.com',
  },
]

** 匹配任意深度子域名(如 a.example.coma.b.example.com)。

Q: 生产环境如何避免每次部署手动更新域名列表?

A: 三种方案:

  1. 环境变量:在 next.config.js 中读取 process.env.ALLOWED_IMAGE_DOMAINS
  2. 通配符:如果域名有规律,使用 remotePatterns 通配符。
  3. 自定义图片代理:通过 API 路由转发图片请求,在代理层动态控制权限。

相关深度解决方案

在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Next.js App Router Metadata 不更新?排查与解决方案

在配置当前服务时,如果您需要实现更复杂的架构或多源数据整合,建议配合参考我们整理的 Next.js Server Actions 请求体大小限制:配置、排查与生产实践