I used simple custom MyUploadAdapter following the ckeditor5 online document.
Images show up from both copy-paste and file upload dialog, and uploaded to the server. But once clicked save the textarea content to my server, the image src is empty, shown as:
<figure class="image"><img></figure>
<figure class="image"><img src="" alt="16 Days of Activism | The Rose Campaign - Women in Crisis"></figure>
The libray I am using: https://cdn.ckeditor.com/ckeditor5/19.0.0/classic/ckeditor.js
Here are the codes:
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();
}
}
}
Sorry, nothing wrong with the code. This issue is caused by server side data not being clean:
it only allows registered users to do this file upload, which causes some unvisible stuff in the response, so xmlhttprequest cannot handle it properly.
I used ob_end_clean() to cast off cached data, and it works now
thanks
I think you should try.
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 );
} );
Your MyUploadAdapter
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();
}
}
}
Yes, Your are right. It only allows registered users to do this file upload. If you upload image on server then you should write a function to upload image. Like this,
We write this code in C# language.
[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});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.