React使用ckEditor5实现图片上传,自定义图片上传适配器

image.png

简单的上传适配器

介绍:现成的简单的上传适配器,简单,只需要提供uploadUrl。
不足:不能定制,如:另外携带参数,返回处理等
配置

import { SimpleUploadAdapter } from '@ckeditor/ckeditor5-upload';

// config中
  plugins: [ SimpleUploadAdapter, /* ... */ ],
  toolbar: [ /* ... */ ],
  simpleUpload: {
        // The URL that the images are uploaded to.
        uploadUrl: 'http://example.com',
  
        // Enable the XMLHttpRequest.withCredentials property.
        withCredentials: true,
  
        // Headers sent along with the XMLHttpRequest to the upload server.
        headers: {
            'X-CSRF-TOKEN': 'CSRF-Token',
            Authorization: 'Bearer <JSON Web Token>'
        }
    }

自定义上传适配器

介绍

介绍:自己定义上传适配器,可以定制一些项目特定的需求。
如下定制实现了:

  1. 上传携带参数userId等;
  2. 上传小于10KB转Base64显示,大于10KB则call api拿到res的url回显到editor

tip:ckEditor5上传 call api返回地址怎么拼可以拿到图片呢 <<< 你要在FE加上 [API HOST], e.g. http://10.89.104.58:8000/

自定义上传适配器

ck-Image-upload-adapter.ts(自定义上传适配器-封装代码)

class MyUploadAdapter {
  userId: any;
  loader: any;
  draftMessageId: string;
  xhr: any;
  constructor(loader: any, userId: any, draftMessageId: string) {
    this.loader = loader;
    this.userId = userId;
    this.draftMessageId = draftMessageId;
  }

  upload() {
    return this.loader.file.then(
      (file: File) =>
        new Promise((resolve, reject) => {
          this._initRequest();
          this._initListeners(resolve, reject, file);
          this._sendRequest(file);
        }),
    );
  }

  abort() {
    if (this.xhr) {
      this.xhr.abort();
    }
  }

  _initRequest() {
    const xhr = (this.xhr = new XMLHttpRequest());
    // 修改为自己项目的接口地址
    xhr.open('POST', '/apis/sma-adm/api/mail/sma-upload-draft-msg-attch', true);
    xhr.responseType = 'json';
  }

  _initListeners(resolve: any, reject: any, file: File) {
    const xhr = this.xhr;
    const loader = this.loader;
    const genericErrorText = `图片${file.name}上传失败`;

    xhr.addEventListener('error', () => reject(genericErrorText));
    xhr.addEventListener('abort', () => reject());
    xhr.addEventListener('load', () => {
      // 这里限制了一下图片上传大小
      // const isLt2M = file.size / 1024 / 1024 < 2;
      // if (!isLt2M) {
      //   return reject(`图片${file.name}大小超出2M,请重新上传`);
      // }
      const response = xhr.response;
      if (!response || response?.status?.code !== 0) {
        return reject(response && response.error ? response.error.message : genericErrorText);
      }
      // baseUrl本地写死,线上从location拿origin
      const buildUrl = 'http://10.89.104.58:8080';
      const hostUrl = location.origin;
      const baseUrl = process.env.NODE_ENV === 'development' ? buildUrl : hostUrl;
      // 这里要根据后端接口取图片地址
      resolve({
        default: baseUrl + response.payload?.data?.attachmentPreviewUrl,
      });
    });
    if (xhr.upload) {
      xhr.upload.addEventListener('progress', (evt: any) => {
        if (evt.lengthComputable) {
          loader.uploadTotal = evt.total;
          loader.uploaded = evt.loaded;
        }
      });
    }
  }

  _sendRequest(file: File) {
    // 图片上传大小 >10KB call api返回imageurl显示到editor;<10KB转base64显示
    const isLt10KB = file.size / 1024 < 10;
    if (isLt10KB) {
      this.abort();
      return;
    }
    const data = new FormData();
    // 'file'要根据自己的接口字段填写
    data.append('draftMessageId', this.draftMessageId);
    data.append('userId', this.userId);
    data.append('attachType', 'IMAGE');
    data.append('file', file);
    this.xhr.send(data);
  }
}

export const CustomUploadAdapterPlugin = (editor: any, userId: any, draftMessageId: string) => {
  editor.plugins.get('FileRepository').createUploadAdapter = (loader: any) => {
    return new MyUploadAdapter(loader, userId, draftMessageId);
  };
};

编辑器使用

tip:editor组件中使用,editorConfig参考文章:react使用CKEditor5,两种使用方式(在线构建器和从源代码构建)。附国际化


  // 获取项目中登录等信息
  const currentUser = useSelector((state: RootState) => state.userSliceReducer.currentUser);
  const { draftMessageId } = useSelector((state: RootState) => state.composeMailDraftIdReducer);
  // 设置上传适配器插件,并传参
  editorConfig.extraPlugins = [
    (editor: any) => CustomUploadAdapterPlugin(editor, currentUser?.userId, draftMessageId),
  ];

  return (
      <div className="ckeditor">
        <CKEditor
          editor={ClassicEditor}
          config={editorConfig}
          data={html}
          onChange={(_event, editor) => {
            const data = editor.getData();
            handleSetHtml(data);
          }}
        />
      </div>
    );

大功告成,去试试吧!

参考:CKEditor5基本使用,图片上传,添加插件

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值