如何在 CKEditor 5 中启用图片上传支持?

新手上路,请多包涵

我将在我的项目中使用 ckeditor v5。我尝试使用图像插件,但找不到足够的信息。

如果您在 此处 看到演示,您可以使用拖放轻松上传图像。但是当我尝试使用下载气球 zip 尝试拖放图像时,没有任何反应。也没有错误。

有没有办法在可下载的变体中使用此图像支持?

原文由 Lukas Gund 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

是的,图像上传包含在所有可用的构建中。但是,为了使其工作,您需要配置一个现有的上传适配器或编写您自己的上传适配器。简而言之,上传适配器是一个简单的类,其作用是将文件发送到服务器(以任何它想要的方式)并在完成后解析返回的承诺。

您可以在官方 图片上传 指南中阅读更多内容,或查看下方可用选项的简短摘要。

官方上传适配器

有两个内置适配器:

  • 对于需要您在服务器上安装 CKFinder 连接器的 CKFinder。

在服务器上安装连接器后,您可以通过设置 config.ckfinder.uploadUrl 选项将 CKEditor 配置为将文件上传到该连接器:

   ClassicEditor
      .create( editorElement, {
          ckfinder: {
              uploadUrl: '/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files&responseType=json'
          }
      } )
      .then( ... )
      .catch( ... );

您还可以启用与 CKFinder 的客户端文件管理器的完全集成。查看 CKFinder 集成演示 并在 CKFinder 集成 指南中阅读更多内容。

您需要 设置云服务帐户,并在 创建令牌端点 后配置编辑器以使用它:

   ClassicEditor
      .create( editorElement, {
          cloudServices: {
              tokenUrl: 'https://example.com/cs-token-endpoint',
              uploadUrl: 'https://your-organization-id.cke-cs.com/easyimage/upload/'
          }
      } )
      .then( ... )
      .catch( ... );

免责声明: 这些是专有服务。

自定义上传适配器

您还可以编写自己的上传适配器,它将以您想要的方式将文件发送到您的服务器(或您喜欢发送文件的任何地方)。

请参阅 自定义图像上传适配器 指南以了解如何实现它。

一个示例(即没有内置安全性)上传适配器如下所示:

 class MyUploadAdapter {
    constructor( loader ) {
        // CKEditor 5's FileLoader instance.
        this.loader = loader;

        // URL where to send files.
        this.url = 'https://example.com/image/upload/path';
    }

    // Starts the upload process.
    upload() {
        return new Promise( ( resolve, reject ) => {
            this._initRequest();
            this._initListeners( resolve, reject );
            this._sendRequest();
        } );
    }

    // Aborts the upload process.
    abort() {
        if ( this.xhr ) {
            this.xhr.abort();
        }
    }

    // Example implementation using XMLHttpRequest.
    _initRequest() {
        const xhr = this.xhr = new XMLHttpRequest();

        xhr.open( 'POST', this.url, true );
        xhr.responseType = 'json';
    }

    // Initializes XMLHttpRequest listeners.
    _initListeners( resolve, reject ) {
        const xhr = this.xhr;
        const loader = this.loader;
        const genericErrorText = 'Couldn\'t upload file:' + ` ${ loader.file.name }.`;

        xhr.addEventListener( 'error', () => reject( genericErrorText ) );
        xhr.addEventListener( 'abort', () => reject() );
        xhr.addEventListener( 'load', () => {
            const response = xhr.response;

            if ( !response || response.error ) {
                return reject( response && response.error ? response.error.message : genericErrorText );
            }

            // If the upload is successful, resolve the upload promise with an object containing
            // at least the "default" URL, pointing to the image on the server.
            resolve( {
                default: response.url
            } );
        } );

        if ( xhr.upload ) {
            xhr.upload.addEventListener( 'progress', evt => {
                if ( evt.lengthComputable ) {
                    loader.uploadTotal = evt.total;
                    loader.uploaded = evt.loaded;
                }
            } );
        }
    }

    // Prepares the data and sends the request.
    _sendRequest() {
        const data = new FormData();

        data.append( 'upload', this.loader.file );

        this.xhr.send( data );
    }
}

然后可以像这样启用它:

 function MyCustomUploadAdapterPlugin( editor ) {
    editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
        return new MyUploadAdapter( loader );
    };
}

ClassicEditor
    .create( document.querySelector( '#editor' ), {
        extraPlugins: [ MyCustomUploadAdapterPlugin ],

        // ...
    } )
    .catch( error => {
        console.log( error );
    } );

注意: 以上只是一个示例上传适配器。因此,它没有内置的安全机制(例如 CSRF 保护)。

原文由 Reinmar 发布,翻译遵循 CC BY-SA 4.0 许可协议

我正在搜索有关如何使用此控件的信息,发现官方文档相当少。然而,经过多次试验和错误后,我确实让它工作了,所以我想我会分享。

最后,我将 CKEditor 5 简单上传适配器与 Angular 8 一起使用,它工作得很好。但是,您确实需要创建一个安装了上传适配器的自定义构建的 ckeditor。这很容易做到。我假设您已经拥有 ckeditor Angular 文件。

首先,创建一个新的角度项目目录并将其命名为“cKEditor-Custom-Build”或其他名称。不要运行 ng new (Angular CLI),而是使用 npm 来获取要显示的编辑器的基础构建。对于这个例子,我使用的是经典编辑器。

 https://github.com/ckeditor/ckeditor5-build-classic

转到 github 并将项目克隆或下载到新的闪亮构建目录中。

如果您使用的是 VS 代码,请打开目录并打开终端框并获取依赖项:

 npm i

现在您已经有了基础构建,您需要安装一个上传适配器。 ckEditor 有一个。安装此软件包以获取简单的上传适配器:

 npm install --save @ckeditor/ckeditor5-upload

..完成后打开项目中的 ckeditor.js 文件。它在“src”目录中。如果您一直在使用 ckEditor,那么它的内容应该看起来很熟悉。

将新的 js 文件导入到 ckeditor.js 文件中。该文件中将包含大量导入,并将其全部放在底部。

 import SimpleUploadAdapter from '@ckeditor/ckeditor5-upload/src/adapters/simpleuploadadapter';

…接下来将导入添加到您的插件数组中。因为我使用的是经典编辑器,所以我的部分称为“ClassicEditor.builtinPlugins”,将其添加到 TableToolbar 旁边。这就是所有配置。为此不需要额外的工具栏或配置。

构建你的 ckeditor-custom-build。

 npm run build

Angular 的魔力将发挥它的作用,并在您的项目中创建一个“构建”目录。它用于定制构建。

现在打开你的角度项目并为你的新构建创建一个目录。我实际上把我的放在 assets 子目录中,但它可以在任何你可以引用它的地方。

在“src/assets”中创建一个名为“ngClassicEditor”之类的目录,不管你怎么称呼它,然后将构建文件复制到其中(你刚刚创建的)。接下来,在要使用编辑器的组件中,添加带有新构建路径的导入语句。

 import * as Editor from '@app/../src/assets/ngClassicEditor/build/ckeditor.js';

就快完成了…

最后一点是使用适配器用于上传图像的 API 端点配置上传适配器。在您的组件类中创建一个配置。

   public editorConfig = {
simpleUpload: {
  // The URL that the images are uploaded to.
  uploadUrl: environment.postSaveRteImage,

  // Headers sent along with the XMLHttpRequest to the upload server.
  headers: {
    'X-CSRF-TOKEN': 'CSFR-Token',
    Authorization: 'Bearer <JSON Web Token>'
  }
}

};

我实际上在这里使用 环境转换,因为 URI 从开发更改为生产,但如果需要,您可以在其中硬编码一个直接 URL。

最后一部分是在模板中配置您的编辑器以使用您的新配置值。打开您的 component.html 并修改您的 ckeditor 编辑器标签。

      <ckeditor [editor]="Editor" id="editor"  [config]="editorConfig">
      </ckeditor>

而已。你完成了。测试,测试测试。

我的 API 是 .Net API,如果您需要一些示例代码,我很乐意与您分享。我真的希望这会有所帮助。

原文由 Darren Street 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题