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

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。
  • 具体修复步骤:
    1. 新增React状态保存Blob引用:添加const [imageBlobs, setImageBlobs] = useState([]),把每次粘贴的Blob存入这个状态,避免被垃圾回收。
    2. 修正getAsFile调用:这个方法是同步的,不需要加await,直接调用即可。
    3. 将Blob URL写入输入框:不要只在控制台打印,要把图片的Markdown语法追加到input状态里,这样编辑器才能显示图片。
    4. 修复组件属性错误:ReactMarkdown的childrenhow是拼写错误,改成children才能正常渲染内容。

修复后的完整代码:

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![粘贴图片](${blobURL})\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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 07:33:53