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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46765197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:36:46  来源:igfitidea点击:

How to enable image upload support in CKEditor 5?

javascriptckeditorckeditor5

提问by Lukas Gund

I will use the ckeditor v5 into my project. I′ve trying to use the image plugin, but I don′t find enough informations about it.

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

If you see the Demoe here, you easily upload images with Drag&Drop. But when I will try it with the download ballon zip nothing happens when I try to Drag&Drop a image. There is also no error.

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

Is there a way to use this image support in the downladable variant?

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

回答by Reinmar

Yes, image upload is included in all the available builds. In order to make it work, though, you need to configure one of the existing upload adapters or write your own. In short, upload adapter is a simple class which role is to send a file to a server (in whatever way it wants) and resolve the returned promise once it's done.

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

You can read more in the official Image uploadguide or see the short summary of the available options below.

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

Official upload adapters

官方上传适配器

There are two built-in adapters:

有两个内置适配器:

  • For CKFinderwhich require you to install the CKFinder connectors on your server.

    Once you have the connector installed on your server, you can configure CKEditor to upload files to that connector by setting the config.ckfinder.uploadUrloption:

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

    You can also enable full integration with CKFinder's client-side file manager. Check out the CKFinder integration demosand read more in the CKFinder integrationguide.

  • For the Easy Imageservice which is a part of CKEditor Cloud Services.

    You need to set up a Cloud Services accountand once you created a token endpointconfigure the editor to use it:

    ClassicEditor
        .create( editorElement, {
            cloudServices: {
                tokenUrl: 'https://example.com/cs-token-endpoint',
                uploadUrl: 'https://your-organization-id.cke-cs.com/easyimage/upload/'
            }
        } )
        .then( ... )
        .catch( ... );
    
  • 对于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 集成指南中阅读更多内容。

  • 对于属于CKEditor Cloud Services一部分的Easy Image服务

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

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

Disclaimer:These are proprietary services.

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

Custom upload adapter

自定义上传适配器

You can also write your own upload adapter which will send files in the way you want to your server (or wherever you like to send them).

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

See Custom image upload adapterguide to learn how to implement it.

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

An example (i.e. with no security built-in) upload adapter can look like this:

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

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 );
    }
}

Which can then be enabled like this:

然后可以像这样启用:

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 );
    } );

NOTE:The above is just an example upload adapter. As such, it does not have security mechanisms built-in (such as CSRF protection).

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

回答by Darren Street

I was searching for information on how to use this control and found the official documentation rather minimal. I did however get it to work after much trial and error, so I thought I would share.

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

In the end I used the CKEditor 5 simple upload adapter with Angular 8 and it works just fine. You do however need to create a custom build of ckeditor that has the upload adapter installed. It's pretty easy to do. I'am assuming you already have the ckeditor Angular files.

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

First, create a new angular project directory and call it "cKEditor-Custom-Build" or something. Don't run ng new (Angular CLI), but instead use npm to get the base build of the editor you want to show. For this example I am using the classic editor.

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

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

Go to to github and clone or download the project into your new shiny build directory.

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

if you are using VS code open the dir and open a terminal box and get the dependencies:

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

npm i

Right you now have the base build and you need to install an upload adapter. ckEditor has one. install this package to get the simple upload adapter:

现在您已经有了基础版本,您需要安装一个上传适配器。ckEditor 有一个。安装这个包以获得简单的上传适配器:

npm install --save @ckeditor/ckeditor5-upload

..once this is done open the ckeditor.js file in the project. Its in the "src" directory. If you have been playing around with ckEditor then its contents should look familiar.

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

Import the new js file into the ckeditor.js file. There will be a whole load of imports in this file and drop it all the bottom.

将新的 js 文件导入到 ckeditor.js 文件中。此文件中将有大量导入并将其全部删除。

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

...Next add the import to your array of plugins. As I am using the classic editor my section is called "ClassicEditor.builtinPlugins", add it next to TableToolbar. That's it all configured. No additional toolbars or config needed at this end.

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

Build your ckeditor-custom-build.

构建您的 ckeditor-custom-build。

npm run build

The magic of Angular will do its thing and a "build" directory is created in your project. That it for the custom build.

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

Now open your angular project and create a directory for your new build to live. I actually put mine in the assets sub-directory, but it can be anywhere you can reference it.

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

Create a directory within "src/assets" called something like "ngClassicEditor", it doesn't matter what you call it, and copy the build file into it (that you just created). Next in the component that you want to use the editor, add an import statement with the path to the new build.

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

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

nearly done...

就快完成了...

The final bit is to configure the Upload adapter with the API endpoint that the adapter should use to upload images. Create a config in your component class.

最后一点是使用适配器应用于上传图像的 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>'
  }
}

};

};

I'm actually using the environment transformhere as the URI changes from dev to production but you could hardcode a straight URL in there if you want.

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

The final part is to configure your editor in the template to use your new configuration values. Open you component.html and modify your ckeditor editor tag.

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

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

That's it. You are done. test, test test.

就是这样。你完成了。测试,测试测试。

My API is a .Net API and I am happy to share if you need some sample code. I really hope this helps.

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