php 在ckeditor 5中提交时,图像src丢失

4uqofj5v  于 12个月前  发布在  PHP
关注(0)|答案(4)|浏览(111)

我使用了简单的自定义MycodeadAdapter遵循ckeditor5在线文档。
图片在复制粘贴和文件上传对话框中都有显示,并上传到服务器。但是一旦点击保存textarea内容到我的服务器,图片src为空,显示为:

<figure class="image"><img></figure>

<figure class="image"><img src="" alt="16 Days of Activism | The Rose Campaign - Women in Crisis"></figure>

字符串
我正在使用的库:https://cdn.ckeditor.com/ckeditor5/19.0.0/classic/ckeditor.js
下面是代码:

function synchValues()
{
/*
    for(var instanceName in CKEDITOR.instances)
        CKEDITOR.instances[instanceName].updateElement();
CKEDITOR.on('instanceReady', function(){
   $.each( CKEDITOR.instances, function(instance) {
    CKEDITOR.instances[instance].on("change", function(e) {
        for ( instance in CKEDITOR.instances )
        CKEDITOR.instances[instance].updateElement();
    });
   });
});

    document.getElementById('editor').value = editor.getData();
*/


$('textarea.editor').each(function () {
   var $textarea = $(this);
   $textarea.val(CKEDITOR.instances[$textarea.attr('name')].getData());
});

    return true;
}


function MyCustomUploadAdapterPlugin( editor ) {

    editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
        // Configure the URL to the upload script in your back-end here!
        return new MyUploadAdapter( loader );
    };
}

let editor;

ClassicEditor
    .create( document.querySelector( '#editor' ), {
        extraPlugins: [ MyCustomUploadAdapterPlugin ],

        styles: [
            // This option is equal to a situation where no style is applied.
            'full',

            'side',

            // This represents an image aligned to the left.
            'alignLeft',

            'alignCenter',

            // This represents an image aligned to the right.
            'alignRight'
        ],

        image: {
            upload:  {
                types: ['jpeg', 'jpg', 'png', 'gif', 'bmp', 'webp', 'tiff', 'mp3', 'mp4', 'm4v', 'm4a', 'm1v', 'm2v', 'mp2', 'mpa', 'mpe', 'mpeg', 'mpg', 'mpv2', 'wav', 'pdf']
                // Image upload feature options.
            }
        }
    } )
    .then( newEditor => {
        console.log( 'Editor was initialized', newEditor );
        editor = newEditor;
    } )
    .catch( error => {
        console.log( error );
    } );

Here is the upload class:

class MyUploadAdapter {
    constructor( loader ) {
        // The file loader instance to use during the upload.
        this.loader = loader;
    }

    // Initializes the XMLHttpRequest object using the URL passed to the constructor.
    _initRequest() {
        const xhr = this.xhr = new XMLHttpRequest();

        // Note that your request may look different. It is up to you and your editor
        // integration to choose the right communication channel. This example uses
        // a POST request with JSON as a data structure but your configuration
        // could be different.
        xhr.open( 'POST', 'http://...../uploadc.php', true );
        xhr.responseType = 'json';
    }


    // Initializes XMLHttpRequest listeners.
    _initListeners( resolve, reject, file ) {
        const xhr = this.xhr;
        const loader = this.loader;
        const genericErrorText = `Couldn't upload file: ${ file.name }.`;

        xhr.addEventListener( 'error', () => reject( genericErrorText ) );
        xhr.addEventListener( 'abort', () => reject() );
        xhr.addEventListener( 'load', () => {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    const response = xhr.response;
                    if ( response && (response.url || response.urls) ) {
                        resolve( response.url ? { default: response.url } : response.urls );
                    } else if ( response && response.error ) {
                        return reject( response.error.message );
                    } else {
                        resolve( response.url ? { default: response.url } : response.urls );
                    }

                } else {
                    return reject( genericErrorText );
                }
            }

        } );

        // Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded
        // properties which are used e.g. to display the upload progress bar in the editor
        // user interface.
        if ( xhr.upload ) {
            xhr.upload.addEventListener( 'progress', evt => {
                if ( evt.lengthComputable ) {
                    loader.uploadTotal = evt.total;
                    loader.uploaded = evt.loaded;
                }
            } );
        }
    }


    // Prepares the data and sends the request.
    _sendRequest( file ) {
        // Prepare the form data.
        const data = new FormData();

        data.append( 'upload', file );

        // Important note: This is the right place to implement security mechanisms
        // like authentication and CSRF protection. For instance, you can use
        // XMLHttpRequest.setRequestHeader() to set the request headers containing
        // the CSRF token generated earlier by your application.

        // Send the request.
        this.xhr.send( data );
    }


    // Starts the upload process.
    upload() {
        return this.loader.file
            .then( file => new Promise( ( resolve, reject ) => {
                this._initRequest();
                this._initListeners( resolve, reject, file );
                this._sendRequest( file );
            } ) );
    }

    // Aborts the upload process.
    abort() {
        if ( this.xhr ) {
            this.xhr.abort();
        }
    }

}

ebdffaop

ebdffaop1#

对不起,代码没有问题。这个问题是由服务器端数据不干净引起的:
它只允许注册用户上传文件,这会导致响应中出现一些不可见的内容,因此XMLHttpRequest无法正确处理。
我使用ob_end_clean()来摆脱缓存数据,现在它可以工作了
谢谢

pbossiut

pbossiut2#

我觉得你应该试试

ClassicEditor.create( document.querySelector( '#Content' ), {
        
    } )
        .then( editor => {
            window.editor = editor;

            editor.editing.view.document.on( 'keyup', ( evt, data ) => {
            //console.log( `You typed : ${ editor.getData()}` );               
            } );

            editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
                // Configure the URL to the upload script in your back-end here!
                return new MyUploadAdapter( loader );
        };

        
        editor.editing.view.document.on( 'change:isFocused', ( evt, data, isFocused ) => {
            //console.log( `View document is focused: ${ data }.` );
        } );

        //console.log( 'Editor was initialized', editor );
        } )
                .catch( error => {
                    console.error( error.stack );
        } );

字符串
您的MycodeAdapter

class MyUploadAdapter {
    constructor( loader ) {
        // The file loader instance to use during the upload.
        this.loader = loader;
    }

    // Initializes the XMLHttpRequest object using the URL passed to the constructor.
    _initRequest() {
        const xhr = this.xhr = new XMLHttpRequest();

        // Note that your request may look different. It is up to you and your editor
        // integration to choose the right communication channel. This example uses
        // a POST request with JSON as a data structure but your configuration
        // could be different.
        xhr.open( 'POST', 'http://...../uploadc.php', true );
        xhr.responseType = 'json';
    }

    // Initializes XMLHttpRequest listeners.
    _initListeners( resolve, reject, file ) {
        const xhr = this.xhr;
        const loader = this.loader;
        const genericErrorText = `Couldn't upload file: ${ file.name }.`;

        xhr.addEventListener( 'error', () => reject( genericErrorText ) );
        xhr.addEventListener( 'abort', () => reject() );
        xhr.addEventListener( 'load', () => {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    const response = xhr.response;
                    if ( response && (response.url || response.urls) ) {
                        resolve( response.url ? { default: response.url } : response.urls );
                    } else if ( response && response.error ) {
                        return reject( response.error.message );
                    } else {
                        resolve( response.url ? { default: response.url } : response.urls );
                    }

                } else {
                    return reject( genericErrorText );
                }
            }

        } );

        // Upload progress when it is supported. The file loader has the #uploadTotal and #uploaded
        // properties which are used e.g. to display the upload progress bar in the editor
        // user interface.
        if ( xhr.upload ) {
            xhr.upload.addEventListener( 'progress', evt => {
                if ( evt.lengthComputable ) {
                    loader.uploadTotal = evt.total;
                    loader.uploaded = evt.loaded;
                }
            } );
        }
    }


    // Prepares the data and sends the request.
    _sendRequest( file ) {
        // Prepare the form data.
        const data = new FormData();

        data.append( 'upload', file );

        // Important note: This is the right place to implement security mechanisms
        // like authentication and CSRF protection. For instance, you can use
        // XMLHttpRequest.setRequestHeader() to set the request headers containing
        // the CSRF token generated earlier by your application.

        // Send the request.
        this.xhr.send( data );
    }


    // Starts the upload process.
    upload() {
        return this.loader.file
            .then( file => new Promise( ( resolve, reject ) => {
                this._initRequest();
                this._initListeners( resolve, reject, file );
                this._sendRequest( file );
            } ) );
    }

    // Aborts the upload process.
    abort() {
        if ( this.xhr ) {
            this.xhr.abort();
        }
    }

}

9jyewag0

9jyewag03#

我遇到了同样的问题,并通过发送带有'url'属性的JSON响应找到了解决方案。
在我的例子中(我使用Laravel),我是这样实现的:

return response()->json(['url' => $url]);

字符串
这就是我找到解决办法的地方。

epfja78i

epfja78i4#

是的,**你说的对。它只允许注册用户做这个文件上传。如果你在服务器上上传图片,那么你应该写一个函数来上传图片。像这样,
我们用
C#**语言编写此代码。

[Authorize, HttpPost]
public ActionResult UploadImage()
{
    private string filepath = string.Empty;
    private string server = string.Empty;
    private HttpPostedFileBase file = null;
    if (Request.Files.Count > 0)
    {
        file = Request.Files[0];
        if (!Directory.Exists(string.Format(System.Web.HttpContext.Current.Server.MapPath("~/UploadedImage"))))
        {
            Directory.CreateDirectory(string.Format(System.Web.HttpContext.Current.Server.MapPath("~/UploadedImage")));
        }

        server = string.Format(System.Web.HttpContext.Current.Server.MapPath("~/UploadedImage/{0}"), file.FileName);
        file.SaveAs(server);
    }

    filepath = string.Format("/UploadedImage/{0}", file.FileName);

    return Json(new { url = filepath});
}

字符串

相关问题