CKEditor 5 教學 (三),上傳圖片至 Amazon S3

程式技術
sharkHead

要想讓文章的內容更為生動,圖片可以說是必不可少的東西,畢竟圖文並茂的文章絕對是大大的加分。

一般的文章編輯器,都會提供插入圖片的功能。本文中我們會使用 CKEditor 官方提供的 CKFinder 套件,實作一個將圖片插入文章內容中的功能。

關於 CKEditor 的基礎安裝教學,可以查看前兩篇文章:

本次演示是在 Laravel 專案上進行。

如果要啟用圖片上傳的功能,必須要先有 CKEditor 的圖片套件,這個套件在預設時就已經安裝。

有安裝的話,就可以在 ckeditor5-build-classic/src/ckeditor.js 中引入的套件看到以下這行:

import Image from "@ckeditor/ckeditor5-image/src/image";

確認一下你的編輯器上方功能列有圖片上傳的圖案。

2021_07_14_16_50_57_60eea57140159.jpg
預設就會有圖片上傳的功能

這時我們先安裝 ckfinder-laravel-package 這個套件,使用 composer 安裝。

composer require ckfinder/ckfinder-laravel-package

安裝好之後還需要下指令來下載 CKFinder 的檔案,下載的檔案會放在 vendor/ckfinder 裡面。

php artisan ckfinder:download

接下來產出一個設定檔案,可以用來設定上傳檔案種類、大小以及 S3 的相關設定。

這個指令會在 config 資料夾底下生成一個 ckfinder.php

php artisan vendor:publish --tag=ckfinder-config

因為 CKFinder 有自帶 CSRF 保護,因此我們需要更改 Laravel 的 Middleware 設定。

其中一個需要修改的檔案是 app/Http/Middleware/EncryptCookies.php,避免加密 CKFinder 的 cookie。

<?php

namespace App\Http\Middleware;

use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;

class EncryptCookies extends Middleware
{
    /**
     * The names of the cookies that should not be encrypted.
     *
     * @var array
     */
    protected $except = [
    	// 避免 Laravel 加密 CKFinder 的 cookie
        'ckCsrfToken',
    ];
}

另外一個檔案是 app/Http/Middleware/VerifyCsrfToken.php。如果是 CKFinder 的相關網址,就不使用 Laravel 自帶的 CSRF 的保護。

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
    	// CKFinder 的相關路由不使用 Laravel 自帶的 CSRF 的保護
        'ckfinder/*',
    ];
}

然後在 routes/web.php 中加入 CKFinder 的路由。

use CKSource\CKFinderBridge\Controller\CKFinderController;

Route::any('/ckfinder/connector', [CKFinderController::class, 'requestAction'])->name('ckfinder_connector');

之後我們在 CKEditor 的 JS 程式碼中設定 CKFinder 的上傳 URL。

ClassicEditor.create( document.querySelector( '#editor' ), {
	ckfinder: {
		// Upload the images to the server using the CKFinder QuickUpload command.
		uploadUrl: "https://你的網站DNS/ckfinder/connector?command=QuickUpload&type=Images&responseType=json"
    },
})
	.then( editor => {
		console.log( 'Editor was initialized', editor );
	 })
	 .catch( err => {
		console.error( err.stack );
	 });

在設定上傳的設定檔案之前,我們需要在 .env 檔案中設定 S3 的金鑰。

AWS_ACCESS_KEY_ID=S3 的 Key ID
AWS_SECRET_ACCESS_KEY=S3 的 Access Key
AWS_DEFAULT_REGION=S3 的地區代碼
AWS_BUCKET=S3 的 Bucket 名稱

最後就是完成上傳的設定檔案,首先我們先設定 Backends 區塊,這裡使用我們剛剛在 .env 中設定的 S3 金鑰。

/*=================================== Backends ========================================*/
// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_backends

$config['backends']['awss3'] = array(
    'name' => 'awss3',
    'adapter' => 's3',
    'bucket' => env('AWS_BUCKET'),
    'region' => env('AWS_DEFAULT_REGION'),
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'visibility' => 'public',
);

再來設定 Resource Types 的區塊。

剛剛在 JS 程式碼中設定的 UploadUrl,其中的參數 type=Images,代表使用 'name' => 'Images' 這個區塊的上傳設定。

其中的 'backend' => 'awss3',代表要使用 'name' => 'awss3' 的 Backend 區塊設定。

/*================================ Resource Types =====================================*/
// http://docs.cksource.com/ckfinder3-php/configuration.html#configuration_options_resourceTypes

$config['defaultResourceTypes'] = 'Images';

$config['resourceTypes'][] = array(
	// UploadUrl 中的 type=Images 代表要使用這個區塊的上傳設定
    'name' => 'Images',
    // S3 的上傳目錄
    'directory' => 'images/post',
    // 檔案最大容量的限制
    'maxSize' => '1M',
    // 允許的副檔名
    'allowedExtensions' => 'bmp,gif,jpeg,jpg,png',
    'deniedExtensions' => '',
    // 使用剛剛在 Backends 區塊的 AWS S3 設定
    'backend' => 'awss3',
);

如此一來,就可以在文章中插入圖片,寫一個圖文並茂的文章內容了。

2021_07_14_16_51_05_60eea5793d600.png
使用拖曳上傳圖片看看吧
sharkHead
written by
sharkHead

後端打工仔,在下班後喜歡研究各種不同的技術。稍微擅長 PHP,並偶爾涉獵前端開發。個性就像動態語言般隨興,但渴望做事能像囉嗦的靜態語言那樣嚴謹。

0 則留言