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

Next.js中Quill插入Object URL仅显示图片图标问题求助

问题排查与修复方案

1. 修复BlotFormatter的动态导入与模块注册

你的BlotFormatter动态导入未正确返回模块实例,且Quill模块注册时机、配置位置有误,这会导致模块无法加载,同时干扰图片渲染逻辑:

  • 修正动态导入代码,确保返回模块默认导出:
const BlotFormatter = dynamic(
  () => import('quill-blot-formatter').then(mod => mod.default),
  { ssr: false, loading: () => <p>Text Editor Loading...</p> }
);
  • 将blotFormatter配置移至modules对象内(useQuill仅接受modules作为配置项,独立传参无效):
const { quill, quillRef, Quill } = useQuill({
  modules: {
    toolbar: {
      container: TOOLBAR_OPTIONS,
    },
    blotFormatter: {}, // 移至modules中
  },
  clipboard: {
    matchVisual: false,
  },
  theme: 'snow',
  placeholder: 'Describe your question',
});
  • 调整模块注册时机,确保在Quill初始化前完成注册:
useEffect(() => {
  if (Quill && !quill) {
    Quill.register('modules/blotFormatter', BlotFormatter);
  }

  if (quill) {
    quill.getModule('toolbar').addHandler('image', imageHandler);
  }
}, [quill, Quill]);

2. 修正图片插入逻辑的细节

当前insertEmbed调用的Quill.sources.USER可能因作用域问题无法正确访问,直接使用字符串'user'替代即可:

quill.insertEmbed(
  position,
  'image',
  url,
  'user' // 替换Quill.sources.USER,避免引用问题
);

3. 补充内存泄漏防护(可选)

使用URL.createObjectURL后,需在组件卸载时释放内存:

useEffect(() => {
  return () => {
    if (quill) {
      const images = quill.root.querySelectorAll('img');
      images.forEach(img => {
        if (img.src.startsWith('blob:')) {
          URL.revokeObjectURL(img.src);
        }
      });
    }
  };
}, [quill]);

完整修正后的代码

import React, { useEffect, useRef } from 'react';
import dynamic from 'next/dynamic';
import { useQuill } from 'react-quilljs';

const BlotFormatter = dynamic(
  () => import('quill-blot-formatter').then(mod => mod.default),
  { ssr: false, loading: () => <p>Text Editor Loading...</p> }
);

const TOOLBAR_OPTIONS = [
  [{ header: [1, 2, 3, 4, 5, 6, false] }],
  [{ font: [] }],
  [{ list: 'ordered' }, { list: 'bullet' }],
  ['bold', 'italic', 'underline', 'strike'],
  [{ indent: '-1' }, { indent: '+1' }, { align: [] }],
  [{ color: [] }, { background: [] }],
  [{ script: 'sub' }, { script: 'super' }],
  [{ align: [] }],
  ['image', 'blockquote', 'code-block'],
  ['clean'],
];

const QuillEditor = () => {
  const { quill, quillRef, Quill } = useQuill({
    modules: {
      toolbar: {
        container: TOOLBAR_OPTIONS,
      },
      blotFormatter: {},
    },
    clipboard: {
      matchVisual: false,
    },
    theme: 'snow',
    placeholder: 'Describe your question',
  });
  const openInputImageRef = useRef();

  useEffect(() => {
    if (Quill && !quill) {
      Quill.register('modules/blotFormatter', BlotFormatter);
    }

    if (quill) {
      quill.getModule('toolbar').addHandler('image', imageHandler);
    }

    return () => {
      if (quill) {
        const images = quill.root.querySelectorAll('img');
        images.forEach(img => {
          if (img.src.startsWith('blob:')) {
            URL.revokeObjectURL(img.src);
          }
        });
      }
    };
  }, [quill, Quill]);

  const imageHandler = () => {
    openInputImageRef.current.click();
  };

  const quillImageCallback = (e) => {
    e.preventDefault();
    e.stopPropagation();

    if (e.currentTarget?.files?.length > 0) {
      const file = e.currentTarget.files[0];
      const formData = new FormData();
      formData.append('image', file);

      const url = URL.createObjectURL(file);
      quill.focus();
      const range = quill.getSelection();
      const position = range ? range.index : 0;

      quill.insertEmbed(
        position,
        'image',
        url,
        'user'
      );
      quill.setSelection(position + 1);
    }
  };

  return (
    <div>
      <div ref={quillRef} />
      <input
        type="file"
        accept="image/*"
        ref={openInputImageRef}
        onChange={quillImageCallback}
        className="hidden"
      />
    </div>
  );
};

export default QuillEditor;

额外说明

BlotFormatter的作用是提供图片拖拽、缩放、对齐等交互功能,本身不影响图片基础显示。你的核心问题是模块注册错误导致Quill图片渲染逻辑异常,修正后图片即可正常显示。若需将图片上传至服务器,可在quillImageCallback中添加异步请求逻辑,用服务器返回的真实地址替换Object URL。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:50:35