3
votes

L'adaptateur de téléchargement CKEditor envoie la [promesse d'objet] au serveur

J'ai essayé d'implémenter CKEditor5 dans un projet vuejs et après avoir fait fonctionner toute l'infrastructure, je ne parviens pas à télécharger le fichier réel sur un serveur php. Le code appelle le serveur et si je renvoie un message de réussite et une URL de fichier, tout fonctionne correctement. Voici mon code:

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

Cliquez sur l'icône d'image dans la barre d'outils pour afficher correctement la boîte de dialogue de sélection de fichier, et lors de la sélection de fichier, soumettra un message au serveur. Cependant, le fichier binaire n'est pas envoyé, mais simplement:

loader.file
Promise {<pending>}
__proto__: Promise
catch: Æ’ catch()
constructor: Æ’ Promise()
finally: Æ’ finally()
then: Æ’ then()
Symbol(Symbol.toStringTag): "Promise"
__proto__: Object
[[PromiseStatus]]: "pending"
[[PromiseValue]]: undefined

J'ai passé deux jours à regarder tous les autres plugins comme CKFinder et d'autres, et il semble que je reçoive toujours la même chose contenu envoyé au serveur. La ligne

data.append('upload', this.loader.file);

ne semble pas ajouter le fichier réel, ce que je pense qu'il devrait faire.

Ma valeur de this.loader est p>

Form Data

------WebKitFormBoundaryqPGA20WRKz9VvADd
Content-Disposition: form-data; name="upload"

[object Promise]

J'ai essayé d'utiliser leur cloudervice mais pointez vers mes propres URL et cela a permis au téléchargement de fonctionner.

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

J'ai également pu supprimez tout le code de l'adaptateur de téléchargement.

Merci


3 commentaires

Je regardais leur service cloud pour voir si cela envoyait correctement et c'était le cas. Je viens de changer les URL de Cloudserver pour les miennes et cela a fonctionné. J'ai publié les modifications apportées à ma question. Je n'ai pas vraiment résolu pourquoi loader.file ne fonctionnerait pas pour moi, mais à la fin, j'ai téléchargé le fichier.


Il semble que le guide sur les adaptateurs de téléchargement ont un bogue. Désolé. Nous y sommes: github.com/ckeditor/ckeditor5/issues/1618 .


La documentation a été mise à jour et la nouvelle version sera bientôt publiée sur ckeditor.com/docs.


3 Réponses :


1
votes

Utilisez jQuery ajax. Je ne trouve pas d'équivalent en utilisant fetch ou axios. La clé est de définir contentType: false et 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 commentaires

En utilisant VueJS, j'évite toute utilisation de JQuery. Envisageait SummerNote au lieu de CKEditor, mais cela nécessitait JQuery. J'ai installé JQuery juste pour voir si leur composant ajax fonctionnait mais la propriété «postefFile» envoyée au serveur est toujours «[object Promise]».



0
votes

0 commentaires

2
votes

La raison de votre problème est que dans la version 11.0.0 du plugin ckeditor5-upload, l'API a été modifiée, loader.file est maintenant une Promise (voir notes de version ). Malheureusement, les documents n'ont pas été mis à jour en conséquence.

Vous devez ajuster un peu votre fonction d'importation:

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

        } );
    } );
}

Le les documents qui avaient ce problème sont maintenant corrigés et utilisent promise correctement. J'espère que cela résout le problème pour vous!


2 commentaires

J'ai remplacé mon code par celui-ci et le téléchargement était un fichier binaire. Excellent ... cependant, il doit y avoir un autre problème avec mon code en ce sens que l'image apparaîtrait puis disparaîtrait immédiatement. J'ai copié l'exemple de code exact de l'adaptateur à partir des Docs, en remplaçant leur URL par la mienne, et cela a fait l'affaire. Je voudrais savoir pourquoi l'image a été effacée immédiatement après le téléchargement, pourrait avoir quelque chose à voir avec l'auditeur pour progresser, etc. veux passer à autre chose.


Je n'ai pas d'option pour essayer de code maintenant, mais du haut de ma tête, je suppose que vous ne renvoyez pas la propriété url dans la réponse. La réponse AFAIR doit contenir l'url avec le ... eh bien, l'url du fichier après son téléchargement (car il pourrait également être renommé pour éviter les collisions). Cela fait-il l'affaire?