React Markdown编辑器粘贴图片Blob链接返回404问题求助
Blob链接已创建,但访问返回404错误
我正在开发一款Markdown文本编辑器,目前在实现截图等图片的粘贴功能。执行粘贴操作时,代码应在控制台打印粘贴图片的Blob URL,但访问该链接时显示图片不存在。
我在传递图片Blob的过程中哪里出错了?
代码
import { useState } from 'react' import { ReactMarkdown } from 'react-markdown/lib/react-markdown' export default function Home() { const [input, setInput] = useState('') const handlePaste = async(e) => { var items = e.clipboardData.items; let image = [].slice.call(items).filter((obj)=> { // Filter the image items only return obj.type.indexOf('image') !== -1; }) const item = image[0]; console.log(item) // Get the blob of image const blob = await item.getAsFile(); let blobURL = URL.createObjectURL(blob); console.log(blobURL) }; return ( <> <textarea name="" id="" cols="30" rows="10" value={input} onPaste={handlePaste} onChange={(e)=>setInput(e.target.value)} /> <ReactMarkdown childrenhow ={input}/> </> ) }
问题原因与修复方案
- URL失效的核心原因:
URL.createObjectURL生成的临时链接依赖Blob对象的存在。当handlePaste函数执行完毕,局部变量blob会被垃圾回收机制清理,对应的URL直接失效,访问就会返回404。 - 具体修复步骤:
- 新增React状态保存Blob引用:添加
const [imageBlobs, setImageBlobs] = useState([]),把每次粘贴的Blob存入这个状态,避免被垃圾回收。 - 修正
getAsFile调用:这个方法是同步的,不需要加await,直接调用即可。 - 将Blob URL写入输入框:不要只在控制台打印,要把图片的Markdown语法追加到
input状态里,这样编辑器才能显示图片。 - 修复组件属性错误:
ReactMarkdown的childrenhow是拼写错误,改成children才能正常渲染内容。
- 新增React状态保存Blob引用:添加
修复后的完整代码:
import { useState, useEffect } from 'react' import { ReactMarkdown } from 'react-markdown/lib/react-markdown' export default function Home() { const [input, setInput] = useState('') const [imageBlobs, setImageBlobs] = useState([]) const handlePaste = (e) => { const items = e.clipboardData.items; const imageItems = [].slice.call(items).filter(obj => obj.type.startsWith('image')); if (!imageItems.length) return; const item = imageItems[0]; const blob = item.getAsFile(); const blobURL = URL.createObjectURL(blob); // 保存Blob引用,维持URL有效性 setImageBlobs(prev => [...prev, blob]); // 追加图片Markdown到输入框 setInput(prev => `${prev}\n\n`); }; // 组件卸载时回收Blob URL,避免内存泄漏 useEffect(() => { return () => { imageBlobs.forEach(blob => URL.revokeObjectURL(URL.createObjectURL(blob))); }; }, [imageBlobs]); return ( <> <textarea name="" id="" cols="30" rows="10" value={input} onPaste={handlePaste} onChange={(e) => setInput(e.target.value)} /> <ReactMarkdown children={input}/> </> ) }
内容的提问来源于stack exchange,提问作者kawa
相关产品推荐
相关产品推荐

