Я пытался внедрить CKEditor5 в проект vuejs, и после того, как вся инфраструктура заработала, я не могу загрузить фактический файл на сервер php. Код вызывает сервер, и если я возвращаю сообщение об успешном завершении и URL-адрес файла, все работает правильно. Вот мой код:
<template>
...
<ckeditor :editor = "editor" v-model = "details.SystemText" :config = "editorConfig"></ckeditor>
...
</template>
import ClassicEditor from '@ckeditor/ckeditor5-build-classic';
class UploadAdapter {
constructor(loader) {
this.loader = loader;
}
upload() {
return new Promise((resolve, reject) => {
const data = new FormData();
data.append('upload', this.loader.file);
axios({
url: '/index/uploadimage',
method: 'post',
data,
headers: {
'Content-Type': 'multipart/form-data;'
},
withCredentials: false
}).then(response => {
if (response.data.result == 'success') {
resolve({
default: response.data.url
});
} else {
reject(response.data.message);
}
}).catch(response => {
reject ( 'Upload failed');
});
});
}
abort() {
}
}
export default {
data () {
details: {},
editor: ClassicEditor,
editorConfig: {
extraPlugins: [ this.MyCustomUploadAdapterPlugin ],
}
},
methods: {
MyCustomUploadAdapterPlugin ( editor ) {
editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
return new UploadAdapter( loader );
};
},
}
Щелчок по значку изображения на панели инструментов правильно отобразит диалоговое окно выбора файла, а после выбора файла сообщение будет отправлено на сервер. Однако бинарный файл не отправляется, а просто:
Form Data
------WebKitFormBoundaryqPGA20WRKz9VvADd
Content-Disposition: form-data; name = "upload"
[object Promise]
Я провел два дня, просматривая все другие плагины, такие как CKFinder и другие, и, кажется, я всегда получаю один и тот же контент, отправляемый на сервер. Линия
data.append('upload', this.loader.file);
похоже, не добавляется фактический файл, что, я думаю, он должен делать.
Моя ценность this.loader
loader.file
Promise {<pending>}
__proto__: Promise
catch: ƒ catch()
constructor: ƒ Promise()
finally: ƒ finally()
then: ƒ then()
Symbol(Symbol.toStringTag): "Promise"
__proto__: Object
[[PromiseStatus]]: "pending"
[[PromiseValue]]: undefined
Пытался использовать их облачный сервис, но указал на свои собственные URL-адреса, и это заработало для загрузки.
editorConfig: {
cloudServices: {
tokenUrl: '/index/tokenendpoint',
uploadUrl: '/index/uploadimage'
}
}
Я также смог удалить весь код адаптера загрузки.
Спасибо
Кажется, что гид об адаптерах загрузки имеет некоторую ошибку. Простите за это. Готово: github.com/ckeditor/ckeditor5/issues/1618.
Документация была обновлена, и новая версия скоро будет опубликована на ckeditor.com/docs.


Используйте JQuery Ajax. Я не могу найти эквивалент с помощью fetch или axios. Ключом является установка contentType: false и processData: false.
upload() {
return new Promise((resolve, reject) => {
const data = new FormData();
data.append('postedFile', this.loader.file);
$.ajax({
url: '/index/uploadimage',
data,
contentType: false,
processData: false,
type: 'POST',
success: response => {
resolve({
default: response.data.url
});
},
error: () => {
reject('Upload failed');
}
});
});
}
Используя VueJS, я избегаю использования JQuery. Рассматривал SummerNote вместо CKEditor, но для этого требовался JQuery. Установил JQuery только для того, чтобы посмотреть, работает ли их компонент ajax, но свойство «postefFile», отправленное на сервер, по-прежнему «[object Promise]».
Они работают над этим, это ошибка. https://github.com/ckeditor/ckeditor5/issues/1618
Причина вашей проблемы в том, что в версии 11.0.0 плагина ckeditor5-upload был изменен API, loader.file теперь Promise (см. примечания к выпуску). К сожалению, документы не были обновлены соответствующим образом.
Вам нужно немного настроить функцию загрузки:
upload() {
return this.loader.file
.then( uploadedFile => {
return new Promise( ( resolve, reject ) => {
const data = new FormData();
data.append( 'upload', uploadedFile );
axios( {
url: '/index/uploadimage',
method: 'post',
data,
headers: {
'Content-Type': 'multipart/form-data;'
},
withCredentials: false
} ).then( response => {
if ( response.data.result == 'success' ) {
resolve( {
default: response.data.url
} );
} else {
reject( response.data.message );
}
} ).catch( response => {
reject( 'Upload failed' );
} );
} );
} );
}
документы, в которых была эта проблема теперь исправлен и правильно использует промис. Надеюсь, это решит проблему для вас!
Я заменил свой код этим, и загрузка была двоичным файлом. Отлично... однако с моим кодом должна быть какая-то другая проблема, заключающаяся в том, что изображение появляется, а затем сразу же исчезает. Я скопировал точный пример кода адаптера из Документов, заменив их URL своим, и это сработало. Я хотел бы знать, почему изображение было стерто сразу после загрузки, могло ли это иметь какое-то отношение к слушателю для прогресса и т. д. Опубликую, если почувствую необходимость в дальнейшем расследовании, но после времени, которое я потратил на это, я просто хочу двигаться дальше.
У меня нет возможности попробовать какой-либо код сейчас, но я предполагаю, что вы не возвращаете свойство url в ответе. Ответ AFAIR должен содержать URL-адрес с... ну, URL-адрес файла после его загрузки (потому что его также можно было бы переименовать, чтобы избежать конфликтов). Это помогает?
Я просматривал их облачный сервис, чтобы убедиться, что он отправляет правильно, и это было так. Я просто изменил URL-адреса облачного сервера на свои собственные, и это сработало. Я опубликовал изменения в своем вопросе. Не очень понял, почему у меня не работает loader.file, но в итоге файл загрузился.