ckeditor 5中的图像上传不适用于laravel 8
Posted
技术标签:
【中文标题】ckeditor 5中的图像上传不适用于laravel 8【英文标题】:image upload in ckeditor 5 not working with 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>
我需要返回什么响应才能使照片上传正常工作?
【问题讨论】:
【参考方案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>
【讨论】:
以上是关于ckeditor 5中的图像上传不适用于laravel 8的主要内容,如果未能解决你的问题,请参考以下文章
使用 CKEditor CDN 时如何从桌面上传 CKEditor 中的图像?
“ng2-CKEditor”节点模块不适用于打字稿[Angular2]