CKEditor 5图像上传问题

时间:2018-11-20 16:45:22

标签: ckeditor5 easyimage

我在项目中使用了ckeditor5。我必须支持图像上传,因此我必须进行搜索并遵循此stackoverflow article

我创建了一个uploadAdapter,

class UploadAdapter {

constructor( loader, url, t ) {
    this.loader = loader;
    this.url = url;
    this.t = t;
}

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

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

_initRequest() {
    const xhr = this.xhr = new XMLHttpRequest();

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

_initListeners( resolve, reject ) {
    const xhr = this.xhr;
    const loader = this.loader;
    const t = this.t;
    const genericError = t( 'Cannot upload file:' ) + ` ${ loader.file.name }.`;

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

        if ( !response || !response.uploaded ) {
            return reject( response && response.error && response.error.message ? response.error.message : genericError );
        }
        resolve( {
            default: response.url
        } );
    } );

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

_sendRequest() {
    const data = new FormData();
    data.append( 'upload', this.loader.file );
    this.xhr.send( data );
}
}

import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import FileRepository from '@ckeditor/ckeditor5-upload/src/filerepository';
export default class GappUploadAdapter extends Plugin {
    static get requires() {
        return [ FileRepository ];
    }

    static get pluginName() {
        return 'GappUploadAdapter';
    }

    init() {
        const url = this.editor.config.get( 'gapp.uploadUrl' );

        if ( !url ) {
            return;
        }

        this.editor.plugins.get( FileRepository ).createUploadAdapter = loader => new UploadAdapter( loader, url, this.editor.t );
    }
}

现在解释一下。我有2个问题。

  1. 上传后(我在服务器上的上传工作正常,并且返回的格式为{default: url}的有效url,为什么我的图像内容以data-uri的形式插入,而不是以简单的图像演示here的形式插入到url中我希望我的图片像url一样。
  2. 我想收听一种成功的上传图像(具有从上传服务器调用中检索到的图像ID),以便在页面中插入一些内容。如何进行 ? enter image description here enter image description here

感谢帮助。

PS:我正在从https://github.com/ckeditor/ckeditor5-build-classic克隆的git repo中使用命令'npm run build'构建ckeditor。

编辑: 多亏了接受的答复,我发现返回的数据有误。我没有在上传器前端返回任何URL,这导致编辑器图像保持img-data方式。返回有效的URL后,将自动对其进行解析,并且我的编辑器图像包含有效的URL。

image descr

1 个答案:

答案 0 :(得分:3)

如果成功上传后仍然使用data-uri,我将认为服务器响应未正确处理,并且无法检索收到的url。我已经测试了您提供的适配器代码,它可以正常工作(在服务器端使用CKFinder)。我将检查上传服务器响应的外观以及是否可以正确解析。

使用CKFinder时,您将看到:

enter image description here

和已解析的JSON响应:

enter image description here

您可以在以下位置检查适配器中是否正确处理了响应:

xhr.addEventListener( 'load', () => {
    const response = xhr.response;
    ...
}

侦听成功的图像可能很棘手,因为没有与之直接相关的事件。根据您要实现的目标,可以尝试扩展自定义加载程序,以便在收到成功响应(并调用resolve()时)可以执行一些代码。但是,在这种状态下,图像元素仍未使用新的URL更新(在模型,视图和DOM中),并且UploadAdapter无法直接访问editor实例,因此可能很难做任何复杂的事情。

更好的方法可能是监听模型更改,类似于在ImageUploadEditing插件(see code here)中检查图像uploadStatus属性更改的方式:

editor.model.document.on( 'change', () => {
  const changes = doc.differ.getChanges();

  for ( const entry of changes ) {
    const uploaded = entry.type === 'attribute' && entry.attributeNewValue === 'complete' && entry.attributeOldValue === 'uploading';
    
    console.log( entry );
  }
} );

如果它从uploading变为complete,则表示图像已成功上传:

enter image description here

您还可以查看另一个答案,该答案显示了如何使用FileRepository API来跟踪整个上传过程-https://github.com/ckeditor/ckeditor5-image/issues/243#issuecomment-442393578