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

如何在React-Quill内容中上传图片?上传后不显示且URL为空如何解决?

问题诊断
  • 未将自定义imageHandler注册到React Quill的modules配置中,编辑器无法触发该上传逻辑
  • imageHandler仅完成了FormData构造,缺少调用后端上传接口、获取图片外链URL、将URL插入编辑器光标位置的核心逻辑
  • FormData定义在input.onchange回调外部,多次上传会导致FormData中累积冗余的旧文件数据
解决办法
  1. 补充modules配置,将自定义图片处理handler绑定到编辑器工具栏的image按钮
  2. 完善图片上传逻辑,添加上传接口调用、URL插入编辑器的流程
  3. 调整FormData定义位置,避免多次上传产生冗余数据

修改后的完整代码如下:

import React, { useRef, useState } from 'react';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
// 可替换为你项目用的请求库,比如axios
import axios from 'axios';

function Post() {
  const QuillRef = useRef<ReactQuill>(null);
  const [Title, setTitle] = useState("");  
  const [contents, setcontents] = useState("");    

  // 自定义图片上传handler
  const imageHandler = () => {
    const input = document.createElement("input");
    input.setAttribute("type", "file");
    input.setAttribute("accept", "image/*");
    input.click();

    input.onchange = async () => {
      const files = input.files as FileList;
      if (!files || files.length === 0) return;
      
      const formData = new FormData();
      formData.append("image", files[0]);
      
      try {
        // 替换为你项目的图片上传接口地址
        const res = await axios.post('/api/upload/image', formData, {
          headers: { 'Content-Type': 'multipart/form-data' }
        });
        // 从接口返回中拿到可访问的图片URL,根据你的实际返回结构调整
        const imageUrl = res.data.url;
        
        // 将图片插入到编辑器当前光标位置
        const quillEditor = QuillRef.current?.getEditor();
        if (!quillEditor) return;
        const range = quillEditor.getSelection();
        if (range) {
          quillEditor.insertEmbed(range.index, 'image', imageUrl);
          // 插入后将光标移动到图片后面
          quillEditor.setSelection(range.index + 1);
        }
      } catch (err) {
        console.error('图片上传失败', err);
        // 可自行添加上传失败的提示
      }
    }
  }

  // 编辑器配置,必须绑定自定义imageHandler
  const modules = {
    toolbar: {
      container: [
        ['bold', 'italic', 'underline', 'strike'],
        ['link', 'image'],
        [{ list: 'ordered' }, { list: 'bullet' }]
        // 可按需添加其他工具栏按钮
      ],
      handlers: {
        image: imageHandler
      }
    }
  }

  const formats = [
    'bold', 'italic', 'underline', 'strike',
    'link', 'image',
    'list', 'bullet'
    // 要和工具栏配置对应
  ]

  const titleHandler = (e : React.ChangeEvent<HTMLTextAreaElement>) => {
      e.preventDefault()
      setTitle(e.currentTarget.value)
  }

  return (
    <div className="post">
        <ReactQuill
          style={{height : "650px"}}
          ref={QuillRef}
          value={contents || ""}
          onChange={(content, delta, source, editor) => setcontents(editor.getHTML())}
          modules={modules}
          formats={formats}
          theme="snow"
          placeholder="내용을 입력해주세요"
        />
    </div>
  );
}

export default Post;

如果你不需要将图片上传到后端,只想直接转成base64插入编辑器,可以将上传接口部分替换为FileReader逻辑:

const reader = new FileReader();
reader.onload = (e) => {
  const imageUrl = e.target?.result as string;
  // 后续插入编辑器逻辑和上面一致
}
reader.readAsDataURL(files[0]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:36:02