Адаптер загрузки CKEditor отправляет [обещание объекта] на сервер

#image #vue.js #upload #ckeditor5

#изображение #vue.js #загрузка #ckeditor5

Вопрос:

Я пытался внедрить 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);
  

похоже, что фактический файл не добавляется, что, я думаю, он должен делать.

Мое значение этого.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
  

Пытался использовать их cloudservice, но указал на мои собственные URL, и загрузка заработала.

                 editorConfig: {
                    cloudServices: {
                        tokenUrl: '/index/tokenendpoint',
                        uploadUrl: '/index/uploadimage'
                    }
                }
  

Я также смог удалить весь код адаптера загрузки.

Спасибо

Комментарии:

1. Я просматривал их облачный сервис, чтобы проверить, правильно ли он отправляется, и это было так. Я просто изменил URL-адреса cloudserver на свои собственные, и это сработало. Я опубликовал изменения в своем вопросе. На самом деле не решил, почему загрузчик. файл у меня не работал, но в конце концов я загрузил файл.

2. Похоже, что в руководстве по адаптерам загрузки есть какая-то ошибка. Извините за это. Мы над этим работаем: github.com/ckeditor/ckeditor5/issues/1618 .

3. Документация была обновлена, и новая версия будет опубликована на ckeditor.com/docs скоро.

Ответ №1:

Причина вашей проблемы в том, что в версии 11.0.0 плагина загрузки ckeditor5 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' );
            } );

        } );
    } );
}
  

Документы, в которых была эта проблема, теперь исправлены и используют promise должным образом. Надеюсь, это решит проблему для вас!

Комментарии:

1. Я заменил свой код этим, и загрузка была двоичным файлом. Отлично … однако, должно быть, в моем коде есть какая-то другая проблема, из-за которой изображение появляется, а затем немедленно исчезает. Я скопировал точный пример кода адаптера из документов, заменив их URL своим, и это сделало свое дело. Я хотел бы знать, почему изображение было удалено сразу после загрузки, могло иметь какое-то отношение к прослушиванию прогресса и т.д. Опубликую, если почувствую желание продолжить расследование, но после того, как я потратил на это время, я просто хочу двигаться дальше.

2. У меня сейчас нет возможности опробовать какой-либо код, но, исходя из моей головы, я предполагаю, что вы не возвращаете url свойство в ответе. Ответ AFAIR должен содержать URL с… ну, URL файла после его загрузки (потому что его также можно переименовать, чтобы избежать коллизии). Это помогает?

Ответ №2:

Используйте 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');
                }
            });
        });
    }
  

Комментарии:

1. Используя VueJS, я избегаю любого использования jQuery. Рассматривал SummerNote вместо CKEditor, но для этого требовался jQuery. Установил jQuery, просто чтобы посмотреть, работает ли их ajax-компонент, но свойство «postefFile», отправленное на сервер, по-прежнему является «[обещание объекта]».

Ответ №3:

Они работают над этим, это ошибка. https://github.com/ckeditor/ckeditor5/issues/1618