FCKediotr 從改版並重新命名為 CKEditor 後,原本在文字編輯器上插入本地圖片的功能被拿掉了
現在要使用本地上傳的話,需要使用額外的插件 CKFinder,上下圖比較一下,使用後「瀏覽伺服器」「上傳」二個功能才可以打開
底下就紀錄一下怎麼實現這個功能,實作的內容
在VISUAL STUDIO 2010 裡,整合 CKEditor.NET 3.6.2 與 CKFinder 2.2.1 (建置的web 平台是vb語言)
STEP 1 下載及安裝
下載及安裝 CKEditor.NET 3.6.2 的方式,dnowba 在前二篇文章提過了就不贅述
ASP.NET 上使用免費的文字編輯器CKEditor
在ASP.NET (使用VB語言) 修改 CKEdtior
下載及安裝 CKFinder 2.2.1:
到官網下載檔案:http://ckfinder.com/download ,記得要下的是asp.net的專屬版本
下載後,將整個資料夾解壓縮到網站的根目錄下,如下圖,特別注意,如果不想要自已修改一些路徑的話,ckeditor 和 ckfinder 二個資料夾建議放在同一層級裡。目錄下的「_sample」是範本可以刪除,「_source」是源始碼,如果不需要重新編譯的話,那麼刪除也沒關係。
再來就是引用參照檔:加入成為控制項的方法除了「在visual studio裡的工具箱右鍵選擇項目」外,「直接把ckfinder.bin 拖曳到工具箱」也可行。
step 2 設置上傳目錄
這個是最煩人的地方了,在不同的程式語言裡表達路徑的方式本來就不一樣,而路徑又分成絕對和相對路徑,很多安裝出現錯誤訊息大部分都是沒有指對路徑所導致,CKFinder預設上傳的目錄是使用"/ckfinder/userfiles/"目錄,如果要修改的話,修改 ckfinder/config.ascx 檔案,如以下程式碼,如果我們設置了一個名為xexe的網站,那麼路徑設置最好是完整一些,路徑的後頭別忘了加"/"表示在此目錄下放置。
// The base URL used to reach files in CKFinder through the browser. // 上傳資料放置的網路路徑 BaseUrl = "~/ckfinder/userfiles/"; // The phisical directory in the server where the file will end up. If // blank, CKFinder attempts to resolve BaseUrl. // 上傳資料放置的實體路徑,如果空白不填,那麼系統會嘗試反解網路路徑以取得實體路徑。 BaseDir = "C:/inetpub/wwwroot/xexe/ckfinder/userfiles/";
step 3 設置安全性
如下圖,設置好安全性的話,權限不足的人無法使用上傳功能,可以避免被不肖人士侵入網站,步驟有二:
1. 檢查上載目錄權限,必須有寫入的權限。如下圖,在ckfinder 資料夾下(或者是自行設一個供上傳的資料夾) 設定安全性,給IUSR_<ServerName>角色寫入(完全控制) 的權限。提醒,不要在整個網站目錄上開可寫的權限,除了上傳目錄是寫入外,上層的目錄只要能讀取能列表就好了;另外,也請不要開一個使用者everyone 然後給個完全控制,這樣不需要通過瀏覽器就可以輕易到你的網站故作非為了。
2、修改 ckfinder/config.ascx 檔案,如下,把第15行的註解拿掉就可以了,程式碼
return ( Session[ "IsAuthorized" ] != null && (bool)Session[ "IsAuthorized" ] == true ); 意思就是用session值來判斷使用者的權限。
public override bool CheckAuthentication() { // WARNING : DO NOT simply return "true". By doing so, you are allowing // "anyone" to upload and list the files in your server. You must implement // some kind of session validation here. Even something very simple as... // // return ( Session[ "IsAuthorized" ] != null && (bool)Session[ "IsAuthorized" ] == true ); // // ... where Session[ "IsAuthorized" ] is set to "true" as soon as the // user logs on your system. //return false; return (Session["IsAuthorized"] != null && (bool)Session["IsAuthorized"] == true); //return true; }
我們在放置ckfinder的網頁,load事件裡加個驗證的方法,例如「如果帳號密碼正確的話,session(“IsAuthorized”)就設定為true,就可以達到一定的安全程度了,建議千萬不要把上面的參數設成 return true,這樣就是「來者不拒」了,也別像下面那樣在頁面上「門戶洞開」。
3. 最好的方法其實跳出錯誤訊息還是不妥,個人認為沒有權限的話,應該連頁面都不給他看到,直接讓網頁重新導向redirect到另一個畫面,或是把ckfinder這個控件給visible,不過後來想想,如果是整合到ckedtior裡,那麼有可能我們會有讓使用者只可以寫文章貼連結圖床的位置,而不能把圖片存在server裡。
step 4 把ckfinder 整合到 ckeditor 裡
方法有二種,擇一使用:
1、修改 ckediotr/config.js
在CKEDITOR.editorConfig = function (config) 底下加入行2~行7的程式碼,這樣就可以啟用ckeditor的filebrowser檔案瀏覽的按鈕,connector.aspx 和 ckfinder.html 都是ckfinder 解譯的重要編碼,所以導向路徑要和你安裝ckfinder的路徑一致。
CKEDITOR.editorConfig = function (config) { config.filebrowserBrowseUrl = 'ckfinder/ckfinder.html'; config.filebrowserImageBrowseUrl = 'ckfinder/ckfinder.html?Type=Images'; config.filebrowserFlashBrowseUrl = 'ckfinder/ckfinder.html?Type=Flash'; config.filebrowserUploadUrl = 'ckfinder/core/connector/aspx/connector.aspx?command=QuickUpload&type=Files'; config.filebrowserImageUploadUrl = 'ckfinder/core/connector/aspx/connector.aspx?command=QuickUpload&type=Images'; config.filebrowserFlashUploadUrl = 'ckfinder/core/connector/aspx/connector.aspx?command=QuickUpload&type=Flash'; };
第1種方式適合全域性的調用,意思就是網站上所有使用ckeditor的都會啟用ckfinder ,都可以透過文字編輯器的插入圖片功能「間接」使用檔案上傳。
2、在頁面程式碼onload的階段載入啟用,一樣注意路徑問題
Protected Overrides Sub OnLoad(e As EventArgs) Dim _FileBrowser As New CKFinder.FileBrowser _FileBrowser.BasePath = "ckfinder/" _FileBrowser.SetupCKEditor(CKEditorControl1) End Sub
第2種方式適合用在「某頁面的CKEDITOR開放檔案上傳功能,另一個有ckeditor 頁面就不需要。」這個時候在頁面上寫上段程式碼。
個人認為第二種比較適當。
可能出現的錯誤及解決方法:
1. 在使用檔案上傳的功能時,出現「無法載入型別:'CKFinder.Connector.Connector'」的錯誤,錯誤圖片及訊息如下:
Server Error in '/' Application. Parser Error Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately. Parser Error Message: Could not load type 'CKFinder.Connector.Connector'. Source Error: Line 1: <%@ Page Language="c#" Inherits="CKFinder.Connector.Connector" Trace="false" AutoEventWireup="false" %> Line 2: <%@ Register Src="../../../config.ascx" TagName="Config" TagPrefix="CKFinder" %> Line 3: <%-- Source File: /ckfinder/core/connector/aspx/connector.aspx Line: 1 Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.237
解決方式:
(1)一開始我以為是 framework 版本的問題,以前曾經有過經驗是VISUAL STUDIO 2005開發的網站/專案 (是framework 2.0)要移到VISUAL STUDIO 2010 (預設是framework 4.0執行)。不過後來從以下幾點澄清了這個誤解:
查了一下 CKFinder 官網並沒有特別提到CKFinder 是用什麼framework環境開發,再檢查一下開放源始碼裡雖使用到framework裡的函數(就是用using來取得一些framework已經定義好的命名空間),但並沒有錯誤(在開發環境下debug一下就知道了)
後來證實了一下,在IIS裡把應用程式集區改為原來的defaultAppPool。網站裡web.config也改了編譯方式,結果還是一樣。
(2) 再來就把錯誤訊息給po到google上,看看是不是有解決的solution,大部分的訊息都是說沒有引用 ckfinder.dll 導致找不到 'CKFinder.Connector.Connector' ,這個自然不用求證,有放就是有放,再重放一次結果也一樣,除非官方發出來的bin檔是有問題的(那麼應該這麼專業的coding應該會很快釋出修正,這個版本發出也3個多月了)。尤其像這種已經包起來的bin檔我們也沒法子自行修改,dnowba有試著把「_resorce資料夾」的資料「ckfinder\_source\CKFinder.Net.csproj」重新編譯,還是沒結果。
(3) 一開始測試的時候,我都是在client 端測試 (這種檔案需要上傳到server的,我通常都直接找台client來試,比較不會出錯),因為前面我想到編譯的問題,所以想會不會改了一些檔案後,還需要重新編譯一次,就是重新啟動一次IIS (突發奇想,到了這邊完全沒理論的亂試了),索性就重新啟動IIS,然後在SERVER端開了個簡易的IIS PORT來測試,沒想到在client端執行不了的程式,在server竟然跑起來了…
這個地方我先想到的是「防火牆」的問題,會不會ckfinder 要配合一些特定的port才能上傳檔案,這個想法雖然白痴但是我還是試了…邊試邊想自已真的白痴,如果port鎖住了那麼出現的錯誤「HTTP 404 - 找不到檔案」之類的訊息吧,沒道理看得到網頁。
好了,我還是看看家裡分享器中虛擬伺服器的狀況,再把windows server 和clinet端的軟體防火牆全給關了…結論就是還是白忙一場。(4) 最後…最後…我終於解決了,這個解決方式真的是始料未及啊,下圖裡,我把我的web站台整個設成應用程式(因為我整個網頁都是用互動式寫的,全都要runat server),然後我在使用ckfinder的時候,也很直覺的把ckfinder這個資料夾轉換成應用程式了,就是這個「多此一舉」,讓我折騰了二天…
唉…iis的錯誤訊息真的是很妙,「無法載入型別」和「多此一舉」到底有什麼關係。
2.在瀏覽器上chrome 可能會看不到上傳的頁面:
為ckfinder 加入plugin 插件
插件的功能是官方開發ckfinder時關注的重點之一,官方的想法是希望透過開源的方式,加入更多的第三方開發者來豐富ckfinder的功能,所以利用插件的方式,每個插件的編譯碼各自獨立,只要在ckfinder的地方導入編譯碼路徑就能實現,官方提供了三個範例供參考,在下載ckfinder裡面的plugins資料夾裡,這三個功能都還不錯,dnowba 學藝不精,javascript 只看得懂幾個字的程度談不上開發,這裡就只是介紹一下這三個還不賴的範例,最後告訴大家怎麼「啟用」
1、第一個範例插件:這個plugin 名為「fileeditor」,針對某些文件 (例如txt、html、js、php ),可以進行「在線編輯」
如果上傳的文件符合要求的格式時,在檔案上右鍵選單,上頭就會多一個「edit」的選項。
選擇edit時,就會出現編輯視窗
官方是說會有「程式碼高亮顯示」的功能,我目前測試的xml檔沒看到,看來只限於html, .js, .php 這三個檔案。
底下就是上傳html,編輯時就有高亮顯示,下圖另外又反應了文字編碼的問題…
2、 第二個範例插件:這個plugin 名為「imageresize」,功能是可以設定圖片大小,一般來說這種功能是有上傳圖片還沒到伺服端前,這個「imageresize」則是針對已上傳的圖片(已經在server端)
如下圖,如果是圖片格式的檔案,在圖上右鍵會看到「resize」的選項
點選後resize的選項可以有幾種small、mediun、large三種固定格式,若都不合意就自訂長寬。
3、第三個範例插件:這個plugin 名為「watermark」,就是為上傳的圖片檔案自動加上一個浮水印。
上面這三個功能可以說是在server端裡實現的,雖然我不知道是不是真的 ( 嗯,如果client 的使用者有權限去使用server端裡的這些資源,那會不會有有心人士利用這個來攻擊server服務器。比方說上傳圖片後一直用機器人程式「resize」,加重server的負擔來達到癱瘓主機的目的。) 好的,話雖如此,我還是要說明一下怎麼「啟用」這幾個附加功能。
ckfinder/config.ascx 裡頭,加入以下程式碼
// Optional: enable extra plugins (remember to copy .dll files first). // 啟用三個附加的功能:FileEditor Plugins = new string[] { "CKFinder.Plugins.FileEditor, CKFinder_FileEditor", "CKFinder.Plugins.ImageResize, CKFinder_ImageResize", "CKFinder.Plugins.Watermark, CKFinder_Watermark" }; // Settings for extra plugins. //// 下面是設定調整圖片大小ImageResize plugin的參數,設定三種定制大小的長、寬 PluginSettings = new Hashtable(); PluginSettings.Add("ImageResize_smallThumb", "90x90" ); PluginSettings.Add("ImageResize_mediumThumb", "120x120" ); PluginSettings.Add("ImageResize_largeThumb", "180x180" ); // Name of the watermark image in plugins/watermark folder // 下面是設定浮水印Watermark plugin的參數,包含浮水印圖片名稱、靠右間距、靠下間距、浮水印品質、透明度) PluginSettings.Add("Watermark_source", "logo.gif" ); PluginSettings.Add("Watermark_marginRight", "5" ); PluginSettings.Add("Watermark_marginBottom", "5" ); PluginSettings.Add("Watermark_quality", "90" ); PluginSettings.Add("Watermark_transparency", "80" );
接下來把函式庫給加到bin資料夾去,三個插件各自有各自的bin檔,路徑位置不多說,看圖對照吧。
其他功能的調整設定
CKFinder 除了搭配 CKEditor 使用外,其實也可以獨立當作檔案管理的介面,官方也有包成一個控制項來使用,頁面上要使用的話,就是直接把這個控件拉到頁面上就可以了。所以可以整個當作web界面的檔案總管,功能算是措措有餘了。像下圖dnowba就故意把文字編輯器和ckfinder的界面分別開來。在插入圖片時其實就可以先參照位置。
ckfinder的主要設定參數都放在ckfinder/config.ascx 檔案
官方在這個參數設定檔案已經有很貼心的加註設定要點了,這裡dnowba 照著順序,把官方的說明給中文化,略解釋註解在程式碼中:
// Thumbnail settings. //預覽縮圖功能設定 // "Url" is used to reach the thumbnails with the browser, while "Dir" // points to the physical location of the thumbnail files in the server. Thumbnails.Url = BaseUrl + "_thumbs/"; if ( BaseDir != "" ) { Thumbnails.Dir = BaseDir + "_thumbs/"; } Thumbnails.Enabled = true; Thumbnails.DirectAccess = false; Thumbnails.MaxWidth = 100; Thumbnails.MaxHeight = 100; Thumbnails.Quality = 80; // Set the maximum size of uploaded images. If an uploaded image is // larger, it gets scaled down proportionally. Set to 0 to disable this // feature. //設定上傳圖片檔案的最大值,如果上傳圖檔太大的話也會自動降級,如果不需要限制大小的話,就設定為0 Images.MaxWidth = 1600; Images.MaxHeight = 1200; Images.Quality = 80; // Indicates that the file size (MaxSize) for images must be checked only // after scaling them. Otherwise, it is checked right after uploading. // 在上傳圖檔前是否檢查圖片大小 CheckSizeAfterScaling = true; // Increases the security on an IIS web server. // If enabled, CKFinder will disallow creating folders and uploading files whose names contain characters // that are not safe under an IIS 6.0 web server. // 增加IIS的安全性,禁止上傳的檔案、資料夾命名含有特定符號 DisallowUnsafeCharacters = true; // Due to security issues with Apache modules, it is recommended to leave the // following setting enabled. It can be safely disabled on IIS. // 這個和APACHE有關,如果是使用IIS架站的話就不用理他 ForceSingleExtension = true; // For security, HTML is allowed in the first Kb of data for files having the // following extensions only. // 允許 HTML 上可直讀的文件檔案名 (而且可以用現有的IIS 解譯) HtmlExtensions = new string[] { "html", "htm", "xml", "js" }; // Folders to not display in CKFinder, no matter their location. No // paths are accepted, only the folder name. // The * and ? wildcards are accepted. // 也是安全性的設定,不懂就用預設的吧 HideFolders = new string[] { ".svn", "CVS" }; // Files to not display in CKFinder, no matter their location. No // paths are accepted, only the file name, including extension. // The * and ? wildcards are accepted. // 也是安全性的設定,不懂就用預設的吧 HideFiles = new string[] { ".*" }; // Perform additional checks for image files. SecureImageUploads = true; // The session variable name that CKFinder must use to retrieve the // "role" of the current user. The "role" is optional and can be used // in the "AccessControl" settings (bellow in this file). //設置使用者權限,可將使用者分成若干群組來分別控制他們的使用權限。 // session名稱如下 RoleSessionVar = "CKFinder_UserRole"; // ACL (Access Control) settings. Used to restrict access or features // to specific folders. // Several "AccessControl.Add()" calls can be made, which return a // single ACL setting object to be configured. All properties settings // are optional in that object. // Subfolders inherit their default settings from their parents' definitions. // // - The "Role" property accepts the special "*" value, which means // "everybody". // - The "ResourceType" attribute accepts the special value "*", which // means "all resource types". AccessControl acl = AccessControl.Add(); acl.Role = "*"; acl.ResourceType = "*"; acl.Folder = "/"; acl.FolderView = true; acl.FolderCreate = true; acl.FolderRename = true; acl.FolderDelete = true; acl.FileView = true; acl.FileUpload = true; acl.FileRename = true; acl.FileDelete = true; // Resource Type settings. // A resource type is nothing more than a way to group files under // different paths, each one having different configuration settings. // Each resource type name must be unique. // When loading CKFinder, the "type" querystring parameter can be used // to display a specific type only. If "type" is omitted in the URL, // the "DefaultResourceTypes" settings is used (may contain the // resource type names separated by a comma). If left empty, all types // are loaded. // 設置可上傳檔案的檔案類型,分為Files、Images、Flash三資料夾,各自設定可以上傳的格式 // 名稱需注意大小寫,例如若設定可上傳DOC,那格式為doc的檔案將不可以上傳 DefaultResourceTypes = ""; ResourceType type; type = ResourceType.Add( "Files" ); type.Url = BaseUrl + "files/"; type.Dir = BaseDir == "" ? "" : BaseDir + "files/"; type.MaxSize = 0; type.AllowedExtensions = new string[] { "7z", "aiff", "asf", "avi", "bmp", "csv", "doc", "docx", "fla", "flv", "gif", "gz", "gzip", "jpeg", "jpg", "mid", "mov", "mp3", "mp4", "mpc", "mpeg", "mpg", "ods", "odt", "pdf", "png", "ppt", "pptx", "pxd", "qt", "ram", "rar", "rm", "rmi", "rmvb", "rtf", "sdc", "sitd", "swf", "sxc", "sxw", "tar", "tgz", "tif", "tiff", "txt", "vsd", "wav", "wma", "wmv", "xls", "xlsx", "zip","html","htm" }; type.DeniedExtensions = new string[] { }; type = ResourceType.Add( "Images" ); type.Url = BaseUrl + "images/"; type.Dir = BaseDir == "" ? "" : BaseDir + "images/"; type.MaxSize = 0; type.AllowedExtensions = new string[] { "bmp", "gif", "jpeg", "jpg", "png" }; type.DeniedExtensions = new string[] { }; type = ResourceType.Add( "Flash" ); type.Url = BaseUrl + "flash/"; type.Dir = BaseDir == "" ? "" : BaseDir + "flash/"; type.MaxSize = 0; type.AllowedExtensions = new string[] { "swf", "flv" }; type.DeniedExtensions = new string[] { }; }
最後再提醒大家,CKFinder、CKEditor 有分多個應用版本,本篇是asp.net的應用,如果你使用不同版本,還是請參考原廠的說明為主。
沒有留言:
張貼留言