You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Next.js 12 API路由获取受保护图片至Next Image组件是否可行?

问题描述

后端图片受Basic Authentication保护,由于Next.js 12的Image组件不支持设置自定义HTTP请求头,我通过创建Next.js API路由来为请求添加Basic Auth请求头,并将该路由作为Image组件的图片地址,代码如下:

API路由代码(pages/api/image/index.ts)

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const id = req.query.id;
  const response = await axios({
    method: "get",
    url: `https://protected-images.com/images/${id}`,
    responseType: "stream",
    headers: {
      Authorization: `Basic ${decodeURIComponent(token)}`,
    },
  });
  response.data.pipe(res);
}

Image组件使用代码

<Image
  src={`/api/image/${id-of-protected-image}`}
  alt={title || ""}
  layout={"fill"}
  objectFit={objectFit}
  objectPosition={objectPosition}
  className={className || ""}
/>

请问:

  1. 该方案是否会导致Vercel平台上无服务器函数的使用率过高?
  2. 这是Next.js 12中渲染受保护图片的可行方案吗?
  3. 是否存在替代方案?

回答

1. 是否会导致Vercel无服务器函数使用率过高?

会有明显的风险。因为每一次图片请求都会触发一次API路由的无服务器函数调用:

  • 页面包含多张图片、或者有大量用户访问时,函数调用次数会快速累积
  • Vercel的免费/基础套餐有函数调用次数限制,超出后会产生额外费用或限制服务
  • 哪怕是付费套餐,高频调用也会增加成本,而且函数冷启动还可能拖慢图片加载速度

2. 是否是Next.js 12中渲染受保护图片的可行方案?

属于临时能用但不适合长期用的方案:

  • 功能上确实能实现需求,正常加载受Basic Auth保护的图片
  • 但缺陷很突出:函数调用成本高、多了一次中转请求导致性能损耗、默认没有缓存优化(每一次请求都要重新从后端拉取图片)

3. 替代方案

方案一:用原生img标签配合fetch获取Blob

如果不需要Next Image的自动优化功能,可以直接用原生<img>标签,先通过fetch带Auth头获取图片Blob,再转成Data URL使用:

import { useState, useEffect } from 'react';

function ProtectedImage({ id, alt }) {
  const [imageUrl, setImageUrl] = useState('');

  useEffect(() => {
    const fetchImage = async () => {
      const response = await fetch(`https://protected-images.com/images/${id}`, {
        headers: {
          Authorization: `Basic ${decodeURIComponent(token)}`,
        },
      });
      const blob = await response.blob();
      setImageUrl(URL.createObjectURL(blob));
    };
    fetchImage();
    return () => URL.revokeObjectURL(imageUrl);
  }, [id]);

  return <img src={imageUrl} alt={alt} />;
}

注意:这种方式没法用Next Image的优化特性,大图片还会占用较多前端内存。

方案二:用Vercel中间件配合Image优化

如果后端图片服务允许Vercel的优化服务访问,可以在next.config.js里把受保护域名加入白名单,再通过中间件给图片请求注入Auth头:

// next.config.js
module.exports = {
  images: {
    domains: ['protected-images.com'],
  },
};

然后创建middleware.js(Next.js 12.2及以上版本支持):

export function middleware(req) {
  if (req.nextUrl.pathname.startsWith('/_next/image')) {
    const targetUrl = new URL(req.nextUrl.searchParams.get('url'));
    return fetch(targetUrl.toString(), {
      headers: {
        Authorization: `Basic ${decodeURIComponent(token)}`,
      },
    });
  }
  return NextResponse.next();
}

这种方式能保留Next Image的优化功能,同时大幅减少无服务器函数的调用次数。

方案三:构建时预拉取图片到静态资源

如果图片内容不频繁更新,可以在项目构建阶段预先拉取所有受保护图片,放到public目录下,之后直接用静态地址引用:

  • 在next.config.js里添加构建脚本,把图片拉取到public/images目录
  • Image组件直接引用/images/${id}路径
    这种方式完全避免了函数调用,性能最优,但只适合静态或低频更新的图片。

内容的提问来源于stack exchange,提问作者Sushant Rajbanshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:13:21