Incorrect Server Response on image drag and drop in CKEditor with Laravel application

CKEditor has a drag and drops image upload feature. But generally, in the Laravel application, it gives an error message “Incorrect Server Response”.
Similar to the following screenshot.

To resolve this issue, we will discuss it in this blog post.

1. Setup the CKEditor in Laravel

Download the CKEditor version 4. After unzipping place folder under the “public” folder of the Laravel application.

Include the CKEditor library in the view file.

<script src="{{ asset('ckeditor/ckeditor.js') }}"></script>

2. Create a controller class, you can ignore this if you already have a controller class for CKEditor.

File upload code

	if($request->hasFile('upload')) {
	
		//get filename with extension
		$fileNameWithExtension = $request->file('upload')->getClientOriginalName();
  
		//get filename without extension
		$fileName = pathinfo($fileNameWithExtension, PATHINFO_FILENAME);
  
		//get file extension
		$extension = $request->file('upload')->getClientOriginalExtension();
  
		//filename to store
		$fileNameToStore = $fileName.'_'.time().'.'.$extension;
  
		//Upload File
		$request->file('upload')->storeAs('public/uploads', $fileNameToStore);

		$CKEditorFuncNum = $request->input('CKEditorFuncNum');
		$url = asset('storage/uploads/'.$fileNameToStore); 
		$msg = 'Image successfully uploaded'; 
		$renderHtml = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')</script>";
		
		// Render HTML output 
		@header('Content-type: text/html; charset=utf-8'); 
		echo $renderHtml;
	}
}

New changes required in controller upload function

public function upload( Request $request ){
	if($request->hasFile('upload')) {
	
		//get filename with extension
		$fileNameWithExtension = $request->file('upload')->getClientOriginalName();
  
		//get filename without extension
		$fileName = pathinfo($fileNameWithExtension, PATHINFO_FILENAME);
  
		//get file extension
		$extension = $request->file('upload')->getClientOriginalExtension();
  
		//filename to store
		$fileNameToStore = $fileName.'_'.time().'.'.$extension;
  
		//Upload File
		$request->file('upload')->storeAs('public/uploads', $fileNameToStore);

		$CKEditorFuncNum = $request->input('CKEditorFuncNum') ? $request->input('CKEditorFuncNum') : 0;
		
		if($CKEditorFuncNum > 0){
		
			$url = asset('storage/uploads/'.$fileNameToStore); 
			$msg = 'Image successfully uploaded'; 
			$renderHtml = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')</script>";
			
			// Render HTML output 
			@header('Content-type: text/html; charset=utf-8'); 
			echo $renderHtml;
			
		} else {
		
			$url = asset('storage/uploads/'.$fileNameToStore); 
			$msg = 'Image successfully uploaded'; 
			$renderHtml = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')</script>";
			return response()->json([
				'uploaded' => '1',
				'fileName' => $fileNameToStore,
				'url' => $url
			]);
		}
		
	}
}

Full controller class code

<?php 
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Storage;

class Editor extends Controller {
	
	public function index(){
		return view('editor');
	}
	
	public function upload( Request $request ){
		if($request->hasFile('upload')) {
		
            //get filename with extension
            $fileNameWithExtension = $request->file('upload')->getClientOriginalName();
      
            //get filename without extension
            $fileName = pathinfo($fileNameWithExtension, PATHINFO_FILENAME);
      
            //get file extension
            $extension = $request->file('upload')->getClientOriginalExtension();
      
            //filename to store
            $fileNameToStore = $fileName.'_'.time().'.'.$extension;
      
            //Upload File
            $request->file('upload')->storeAs('public/uploads', $fileNameToStore);
 
            /* $CKEditorFuncNum = $request->input('CKEditorFuncNum');
            $url = asset('storage/uploads/'.$fileNameToStore); 
            $msg = 'Image successfully uploaded'; 
            $renderHtml = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')</script>";
			
            // Render HTML output 
            @header('Content-type: text/html; charset=utf-8'); 
            echo $renderHtml; */
			
			$CKEditorFuncNum = $request->input('CKEditorFuncNum') ? $request->input('CKEditorFuncNum') : 0;
			
			if($CKEditorFuncNum > 0){
			
				$url = asset('storage/uploads/'.$fileNameToStore); 
				$msg = 'Image successfully uploaded'; 
				$renderHtml = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')</script>";
				
				// Render HTML output 
				@header('Content-type: text/html; charset=utf-8'); 
				echo $renderHtml;
				
			} else {
			
				$url = asset('storage/uploads/'.$fileNameToStore); 
				$msg = 'Image successfully uploaded'; 
				$renderHtml = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')</script>";
				return response()->json([
					'uploaded' => '1',
					'fileName' => $fileNameToStore,
					'url' => $url
				]);
			}
			
        }
	}
	
	public function browse( Request $request ){
		
		$files = Storage::files('public/uploads');
		//dd($files);
		$CKEditorFuncNum = $request->input('CKEditorFuncNum');
		
		$msg = 'Image successfully uploaded'; 
		foreach( $files as $file){
			$url = asset('storage/uploads/'.str_replace('public/uploads/', '', $file));
			$renderHtml = "<script>
			function returnFileUrl() {
				window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url');
				window.close();
			}
			</script>";
			$renderHtml .='<button onclick="returnFileUrl()">Select File</button>';
		}
		
		// Render HTML output 
		@header('Content-type: text/html; charset=utf-8'); 
		echo $renderHtml;
		
	}
}

3. Config CKEditor for textarea / form page.

<div class="container">
	<div class="row align-items-center">
		<div class="col">
			<h1 class="mb-3 text-center">Editor Testing</h1>
			<form method="POST" action="">
				@csrf
				<div class="row">
					<div class="col-lg-12 grid-margin stretch-card">
						<div class="card">
							<div class="card-body">
								@if ($errors->any())
									<div class="alert alert-danger">
										<ul class="">
											@foreach ($errors->all() as $error)
												<li>{{ $error }}</li>
											@endforeach
										</ul>
									</div>
								@endif
								
								<h4 class="card-title">{{ __('Page Content') }}</h4>
								<p class="card-description"></p>
								<div class="row">
									<div class="col-md-12">
										<div class="form-group">
											<label class="label">Page Title</label>
											<input type="text" class="form-control" name="title" value="{{ old('title') }}"/>
										</div>
									</div>
									<div class="col-md-12">
										<div class="form-group">
											<label class="label">Page Sub Heading</label>
											<input type="text" class="form-control" name="sub_title" value="{{ old('sub_title') }}"/>
										</div>
									</div>
									<div class="col-md-12">
										<div class="form-group">
											<label class="label">Page Content</label>
											<textarea class="form-control" id="content" name="content">{{ old('content') }}</textarea>
										</div>
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
				
				<div class="row">
					<div class="col-lg-12">
						<div class="form-group">
							<div class="col-md-12 text-center">
								
								<button type="submit" class="btn btn-primary btn-lg">
									{{ __('Submit') }}
								</button>
							</div>
						</div>
					</div>
				</div>
			</form>
		</div>
	</div>
</div>
&lt;script src="{{ asset('ckeditor/ckeditor.js') }}"&gt;&lt;/script&gt;
&lt;script&gt;
	CKEDITOR.config.allowedContent = true;
    CKEDITOR.replace('content', {
        filebrowserUploadUrl: "{{route('upload', ['_token' => csrf_token() ])}}",
        filebrowserUploadMethod: 'form',
		filebrowserBrowseUrl : "{{asset('ckeditor/filemanager/dialog.php')}}?type=2&editor=ckeditor&fldr=",
		filebrowserImageBrowseUrl : "{{asset('ckeditor/filemanager/dialog.php')}}?type=1&editor=ckeditor&fldr=",
        
    });
&lt;/script&gt;

4. Output

5. Where image will store in Laravel?

The image will store in the Laravel storage folder. For more detail check the Laravel storage documentation.