CKEditor 5 图片上传问题
CKEditor 5 Image Upload Issues
我正在我的项目中使用 ckeditor5。我必须支持图片上传,所以我搜索并关注了这个 Whosebug .
我创建了一个 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 个问题。
- 上传后(我在服务器上的上传工作正常并以
{default: url}
格式返回有效的 url,为什么我的图像内容作为 data-uri 插入而不是 url至于简单的图像演示 here。我希望我的图像像 url 一样。
- 我想听取一种成功的上传图像(带有从上传服务器调用中检索到的图像 ID)以在我的页面中插入一些内容。如何进行 ?
感谢您的帮助。
PS:我正在使用从 https://github.com/ckeditor/ckeditor5-build-classic
克隆的 git 仓库中的命令 'npm run build' 构建 ckeditor
编辑:
感谢接受的回复,我发现返回的数据是错误的。我没有在我的上传器前端返回任何 URL,这导致编辑器图像以 img-data 方式保留。返回有效的 URL 后,它会自动解析,我的编辑器图像包含有效的 url.
如果在成功上传后数据 uri 仍然被使用,我会假设服务器响应没有被正确处理并且接收到的 url 无法被检索。我已经测试了您提供的适配器代码并且它工作正常(在服务器端使用 CKFinder)。我会检查上传服务器响应的外观以及是否可以正确解析。
使用 CKFinder 时您会看到:
和解析的 JSON 响应:
您可以检查您的适配器是否正确处理了响应:
xhr.addEventListener( 'load', () => {
const response = xhr.response;
...
}
监听成功的图片上传可能比较棘手,因为没有直接相关的事件。根据您要实现的目标,您可以尝试扩展自定义加载程序,以便在收到成功响应(并调用 resolve()
时)您可以执行一些代码。然而,在这种状态下,图像元素仍然没有更新(在模型、视图和 DOM 中)新的 URL 和 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
则表示图片上传成功:
您还可以查看另一个答案,其中展示了如何挂接到 FileRepository
API 以跟踪整个上传过程 - https://github.com/ckeditor/ckeditor5-image/issues/243#issuecomment-442393578.
我正在我的项目中使用 ckeditor5。我必须支持图片上传,所以我搜索并关注了这个 Whosebug
我创建了一个 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 个问题。
- 上传后(我在服务器上的上传工作正常并以
{default: url}
格式返回有效的 url,为什么我的图像内容作为 data-uri 插入而不是 url至于简单的图像演示 here。我希望我的图像像 url 一样。 - 我想听取一种成功的上传图像(带有从上传服务器调用中检索到的图像 ID)以在我的页面中插入一些内容。如何进行 ?
感谢您的帮助。
PS:我正在使用从 https://github.com/ckeditor/ckeditor5-build-classic
克隆的 git 仓库中的命令 'npm run build' 构建 ckeditor编辑: 感谢接受的回复,我发现返回的数据是错误的。我没有在我的上传器前端返回任何 URL,这导致编辑器图像以 img-data 方式保留。返回有效的 URL 后,它会自动解析,我的编辑器图像包含有效的 url.
如果在成功上传后数据 uri 仍然被使用,我会假设服务器响应没有被正确处理并且接收到的 url 无法被检索。我已经测试了您提供的适配器代码并且它工作正常(在服务器端使用 CKFinder)。我会检查上传服务器响应的外观以及是否可以正确解析。
使用 CKFinder 时您会看到:
和解析的 JSON 响应:
您可以检查您的适配器是否正确处理了响应:
xhr.addEventListener( 'load', () => {
const response = xhr.response;
...
}
监听成功的图片上传可能比较棘手,因为没有直接相关的事件。根据您要实现的目标,您可以尝试扩展自定义加载程序,以便在收到成功响应(并调用 resolve()
时)您可以执行一些代码。然而,在这种状态下,图像元素仍然没有更新(在模型、视图和 DOM 中)新的 URL 和 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
则表示图片上传成功:
您还可以查看另一个答案,其中展示了如何挂接到 FileRepository
API 以跟踪整个上传过程 - https://github.com/ckeditor/ckeditor5-image/issues/243#issuecomment-442393578.