Next.js加载API返回的Base64图片失败,如何实现懒加载显示?
解决Next.js加载外部HTML图片不显示+懒加载问题
先解决图片显示问题
浏览器只会加载img标签的src属性内容,你现在的src是base64占位图(可能无效),真实地址存在data-src里,核心是把真实地址映射到可加载的属性上,同时配合懒加载逻辑。
1. 用Cheerio处理HTML内容
先安装Cheerio来解析和批量修改HTML:
npm install cheerio
然后在获取API数据后做处理:
import cheerio from 'cheerio'; async function getProcessedHtml() { const apiRes = await fetch('你的外部API地址'); const rawHtml = await apiRes.text(); const $ = cheerio.load(rawHtml); $('img').each((_, imgEl) => { const $img = $(imgEl); const realUrl = $img.attr('data-src'); if (realUrl) { // 保留原base64作为占位,标记懒加载类名 $img.attr('data-original', realUrl); $img.addClass('lazy'); // 如果想直接显示图片,替换这行:$img.attr('src', realUrl); } }); return $.html(); }
实现懒加载(两种实用方案)
方案一:原生浏览器懒加载(零依赖)
现代浏览器原生支持loading="lazy"属性,直接在Cheerio处理时添加即可:
$img.attr('loading', 'lazy');
浏览器会自动在图片进入视口范围时触发加载,不需要额外写JS逻辑。
方案二:结合Next.js Image组件(性能更优)
如果想利用Next.js的图片优化能力(自动压缩、格式转换、响应式适配),可以把HTML中的img标签替换成Next.js Image组件:
- 安装HTML解析工具:
npm install react-html-parser
- 自定义懒加载图片组件:
import Image from 'next/image'; function LazyImage({ node }) { const { 'data-src': realSrc, alt = '', src: placeholder } = node.attribs; return ( <div style={{ position: 'relative', width: '100%', height: 'auto' }}> <Image src={realSrc} alt={alt} fill loading="lazy" sizes="100vw" placeholder="blur" blurDataURL={placeholder} // 用原base64作为模糊占位图 /> </div> ); }
- 在页面中解析并渲染处理后的HTML:
import ReactHtmlParser, { convertNodeToElement } from 'react-html-parser'; import { useState, useEffect } from 'react'; const htmlParseOptions = { transform: (node) => { if (node.type === 'tag' && node.name === 'img') { return convertNodeToElement(LazyImage, node, htmlParseOptions); } return null; }, }; export default function MyPage() { const [content, setContent] = useState(''); useEffect(() => { async function loadContent() { const processedHtml = await getProcessedHtml(); setContent(processedHtml); } loadContent(); }, []); return <div className="content-container">{ReactHtmlParser(content, htmlParseOptions)}</div>; }
额外排查点
如果原base64占位图也不显示,大概率是base64字符串无效。可以把它复制到浏览器地址栏(加上data:image/gif;base64,前缀)测试,无效的话换成通用占位base64:
data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA=
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

