【问题标题】:image upload in ckeditor 5 not working with laravel 8ckeditor 5中的图像上传不适用于laravel 8
【发布时间】:2021-04-25 09:48:21
【问题描述】:

我正在使用 Laravel 8 和 JavaScript 开发一个网站。 我使用ckeditor 5,它工作正常。当我尝试上传照片时出现问题。照片上传完成,但我收到一条错误消息并且没有显示照片。我收到以下标题的错误: “无法上传文件:filename.jpg” 我想我没有向前端返回正确的响应。 我在 route/web.php 文件中有这些代码

Route::group(["middleware"=>"auth","prefix"=>"panel"],function (){
    Route::post('/post/edit/{post_slug}', [PostController::class,"update"])->name("updatePostRoute");
    Route::get('/post/edit/{post_slug}', [RenderPanelController::class,"renderPostEditPage"])->name("renderPostEditPageRoute");
    Route::post('/post/ckeditor/upload', [PostController::class,"upload_image_cke"])->name('ckeditor.upload');
});

在 PostController 中

    public function upload_image_cke(Request $request){
        if ($request->hasFile('upload')) {
            $originName = $request->file('upload')->getClientOriginalName();
            $fileName = pathinfo($originName, PATHINFO_FILENAME);
            $extension = $request->file('upload')->getClientOriginalExtension();
            $fileName = $fileName . '_' . time() . '.' . $extension;

            $request->file('upload')->move(public_path('media'), $fileName);

            $CKEditorFuncNum = $request->input('CKEditorFuncNum');
            $url = asset('media/' . $fileName);
            $msg = 'upload successfully';
            $response = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')</script>";

            @header('Content-type: text/html; charset=utf-8');
            echo $response;

        }
    }

在刀片文件中:

<textarea type="text" class="form-control" name="content" id="content"></textarea>
<meta name="csrf-token" content="{{ csrf_token() }}">

<script src="https://cdn.ckeditor.com/ckeditor5/27.1.0/classic/ckeditor.js"></script>

<script>
    ClassicEditor
        .create( document.querySelector( '#content' ), {
            ckfinder: {
                uploadUrl: '{{route('ckeditor.upload')."?command=QuickUpload&type=Files&responseType=json"}}',
                headers: {
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
                }
            }
        },{
            alignment: {
                options: [ 'right', 'right' ]
            }} )
        .then( editor => {
            console.log( editor );
        })
        .catch( error => {
            console.error( error );
        })
</script>

我需要返回什么响应才能使照片上传正常工作?

【问题讨论】:

    标签: php laravel ckeditor


    【解决方案1】:

    我有另一种方法。希望它适用于您和许多开发者。

    我的做法是为每个用户动态定义一个存储路径($path_url 变量)

    请注意,您必须在终端上运行php artisan storage:link

    web.php

    Route::post('ckeditor/upload', 'App\Http\Controllers\CKEditorController@store')->name('ckeditor.upload');
    

    CKEditorController - 方法存储

    public function store(Request $request)
       {
          $path_url = 'storage/' . Auth::id();
    
          if ($request->hasFile('upload')) {
             $originName = $request->file('upload')->getClientOriginalName();
             $fileName = pathinfo($originName, PATHINFO_FILENAME);
             $extension = $request->file('upload')->getClientOriginalExtension();
             $fileName = Str::slug($fileName) . '_' . time() . '.' . $extension;
             $request->file('upload')->move(public_path($path_url), $fileName);
             $url = asset($path_url . '/' . $fileName);
          }
    
          return response()->json(['url' => $url]);
       }
    

    表格

    <textarea name="body" id="body" class="form-control"></textarea>
    

    现在,您必须定义一个“适配器”来将文件上传到存储

    <script src="https://cdn.ckeditor.com/ckeditor5/27.1.0/classic/ckeditor.js"></script>
    <script>
        //Define an adapter to upload the files
        class MyUploadAdapter {
           constructor(loader) {
              // The file loader instance to use during the upload. It sounds scary but do not
              // worry — the loader will be passed into the adapter later on in this guide.
              this.loader = loader;
    
              // URL where to send files.
              this.url = '{{ route('ckeditor.upload') }}';
    
              //
           }
           // 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();
              }
           }
           // 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', this.url, true);
              xhr.open("POST", this.url, true);
              xhr.setRequestHeader("x-csrf-token", "{{ csrf_token() }}");
              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", () => {
                 const response = xhr.response;
                 // This example assumes the XHR server's "response" object will come with
                 // an "error" which has its own "message" that can be passed to reject()
                 // in the upload promise.
                 //
                 // Your integration may handle upload errors in a different way so make sure
                 // it is done properly. The reject() function must be called when the upload fails.
                 if (!response || response.error) {
                    return reject(response && response.error ? response.error.message : genericErrorText);
                 }
                 // If the upload is successful, resolve the upload promise with an object containing
                 // at least the "default" URL, pointing to the image on the server.
                 // This URL will be used to display the image in the content. Learn more in the
                 // UploadAdapter#upload documentation.
                 resolve({
                    default: response.url,
                 });
              });
              // 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);
           }
           // ...
        }
    
        function SimpleUploadAdapterPlugin(editor) {
           editor.plugins.get("FileRepository").createUploadAdapter = (loader) => {
              // Configure the URL to the upload script in your back-end here!
              return new MyUploadAdapter(loader);
           };
        }
    
        //Initialize the ckeditor
        ClassicEditor.create(document.querySelector("#body"), {
           extraPlugins: [SimpleUploadAdapterPlugin],
        }).catch((error) => {
           console.error(error);
        });
    
    </script>
    

    我希望我有所帮助。一个拥抱!

    【讨论】:

    • $url = Storage::url($request->file('upload')->store('public/uploads'));
    【解决方案2】:

    在 PostController 中

    public function upload_image_cke(Request $request){
        if ($request->hasFile('upload')) {
            $originName = $request->file('upload')->getClientOriginalName();
            $fileName = pathinfo($originName, PATHINFO_FILENAME);
            $extension = $request->file('upload')->getClientOriginalExtension();
            $fileName = $fileName . '_' . time() . '.' . $extension;
    
            $request->file('upload')->move(public_path('media'), $fileName);
    
            $url = asset('media/' . $fileName);
            return response()->json(['fileName' => $fileName, 'uploaded'=> 1, 'url' => $url]);
            
    
        }
    }
    

    在刀片文件中:

    <script>
        ClassicEditor
            .create( document.querySelector( '#content' ), {
                ckfinder: {
                    uploadUrl: '{{route('ckeditor.upload').'?_token='.csrf_token()}}'
                }
            },{
                alignment: {
                    options: [ 'right', 'right' ]
                }} )
            .then( editor => {
                console.log( editor );
            })
            .catch( error => {
                console.error( error );
            })
    </script>
    

    【讨论】:

      猜你喜欢
      • 2015-10-18
      • 2019-05-15
      • 1970-01-01
      • 2022-08-06
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多