程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> FckEditor,遠程圖片下載,插件

FckEditor,遠程圖片下載,插件

編輯:.NET實例教程

有時候我們從其他網頁上拷貝來的內容中含有圖片,當原始地址失效後就會影響讀者閱讀。
所以我制作了這樣一個插件,可以將遠程圖片保存到本地服務器。

聲明:下面的文字是本文不可缺少的部分,轉載請保留,謝謝!
////////////////////////////////////////////////////
作者:武眉博<活靶子.Net>
同時首發於:
    
落伍者   && 博客園  
    
開發者學院   && .Net男孩社區
////////////////////////////////////////////////////
今天轉載了[author]xiaozhuang[/author]朋友的文章同時從博客園服務器上下載了圖片
演示見:
http://www.devedu.com/Doc/DotNet/AspNet/AspNet-AJaxWCF-ServiceADONET-Entity-FrameworkShiXianShuJuLIEBiaoShuJuShaiXuanFenYePaiXuShanChu.ASPx

原理如下:
    1.實現ICallbackEventHandler接口以用啟用客戶端回調。
    2.從當前FckEdiotr內容分析出所有<img標簽,取得src的地址。
    3.回調下載到服務器。
    4.返回下載後位於本服務器上的路徑。
    5.替換當前FckEdiotr內容內對應的<img標簽的src屬性。

其他廢話不多說了,代碼中都有注釋。

如果您熟悉Fckeditor的插件工作流程,請繼續向下閱讀,另請不要留言要我直接提供下載,下面的代碼已經可以完整調試了。
E:\IISROOT\FckTest\FckTest\fckeditor\editor\plugins\remoteimagerubber\remoteimagerubber.ASPx


  1 <%--
  2 使用單頁模型(非代碼後置),是為了便於此插件部署,
  3 不需編譯成dll,只需拷貝remoteimagerubber.ASPx 和 fckplugin.JS 到plugn目錄,
  4 並配置一下fckconfig.JS及相應的語言包,就可以使用了。
  5 --%>
  6 
  7 <%@ Page Language="C#" %>
  8 
  9 <%@ Import Namespace="System.Net" %>
 10 <%--
 11 實現ICallbackEventHandler接口以提供客戶端回調功能。
 12 --%>
 13 <%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
 14 
 15 <script runat="server">
 16     
 17     /// <summary>
 18     /// 此處配置遠程文件保存目錄
 19     /// </summary>
 20     private static readonly string savePath = "~/Uploads/";
 21 
 22     /// <summary>
 23     /// 此處配置允許下載的文件擴展名
 24     /// <remarks>
 25     ///     暫未考慮使用動態網頁輸出的圖片如:http://site/image.ASPx?uid=00001 這樣的URI;
 26     ///  若要實現此功能可讀取流並判斷ContentType,將流另存為相應文件格式即可。
 27     /// </remarks>
 28     /// </summary>
 29     private static readonly string[ ] allowImageExtension = new string[ ] { ".jpg" , ".png" , ".gif" };
 30 
 31     /// <summary>
 32     /// 此處配置本地(網站)主機名
 33     /// </summary>
 34     private static readonly string[ ] localhost = new string[ ] { "localhost" , "www.devedu.com" };
 35 
 36     private string localImageSrc = string.Empty;
 37 
 38     private void Page_Load( object obj , EventArgs args )
 39     {
 40         if ( !Page.IsPostBack )
 41         {
 42             ClientScriptManager csm = Page.ClIEntScript;
 43 

44             string scripCallServerDownLoad = csm.GetCallbackEventReference( this , "args" , "__ReceiveServerData" , "context" );
 45             string callbackScriptDwonLoad = "function __CallServerDownLoad(args , context) {" + scripCallServerDownLoad + "; }";
 46             if ( !csm.IsClIEntScriptBlockRegistered( "__CallServerDownLoad" ) )
 47             {
 48                 csm.RegisterClIEntScriptBlock( this.GetType( ) , "__CallServerDownLoad" , callbackScriptDwonLoad , true );
 49             }
 50         }
 51     }
 52 
 53     #region ICallbackEventHandler 成員
 54 
 55     /// <summary>
 56     /// 返回數據
 57     /// </summary>
 58     /// <remarks>如果處理過程中出現錯誤,則仍然返回遠程路徑</remarks>
 59     /// <returns>服務器端處理後的本地圖片路徑</returns>
 60     public string GetCallbackResult( )
 61     {
 62         return localImageSrc;
 63 
 64     }
 65 
 66     /// <summary>
 67     /// 處理回調事件 
 68     /// </summary>
 69     /// <param name="eventArgument">一個字符串,表示要傳遞到事件處理程序的事件參數</param>
 70     public void RaiseCallbackEvent( string eventArgument )
 71     {
 72 
 73         string remoteImageSrc = eventArgument;
 74 
 75         string fileName = remoteImageSrc.Substring( remoteImageSrc.LastIndexOf( "/" ) + 1 );
 76         string ext = System.IO.Path.GetExtension( fileName );
 77 
 78         if ( !IsAllowedDownloadFile( ext ) )
 79         {
 80             //非指定類型圖片不進行下載,直接返回原地址。
 81             localImageSrc = remoteImageSrc;
 82             return;
 83         }
 84 
 85         Uri uri = new Uri( remoteImageSrc );
 86         if ( IsLocalSource( uri ) )
 87         {
 88             //本地(本網站下)圖片不進行下載,直接返回原地址。
 89             localImageSrc = remoteImageSrc;
 90             return;
 91         }
 92 
 93         try
 94         {
 95             //自動創建一個目錄。
 96             DateTime now = DateTime.Now;
 97             string datePath = string.Format( @"{0}\{1}\{2}\{3}" , now.Year , now.Month.ToString( "00" ) , now.Day.ToString( "00" ) , Guid.NewGuid( ).ToString( ) );
 98 
 99             string localDirectory = System.IO.Path.Combine( Server.MapPath( savePath ) , datePath );
100             if ( !System.IO.Directory.Exists( localDirectory ) )
101             {
102                 System.IO.Directory.CreateDirectory( localDirectory );
103             }
104 
105             string localFilePath = System.IO.Path.Combine( localDirectory , fileName );
106 
107             //不存在同名文件則開始下載,若已經存在則不下載該文件,直接返回已有文件路徑。
108             if ( !System.IO.File.Exists( localFilePath ) )
109             {
110                 ClIEnt.DownloadFile( uri , localFilePath );
111             }
112 
113             string localImageSrc = ResolveUrl( "~/" + localFilePath.Replace( Server.MapPath( "~/" ) , string.Empty ).Replace( "\\" , "/" ) );
114 
115         }
116         catch
117     &nbsp;   {
118             //下載過程中出現任何異常都不拋出(  有點狠啊 :)  ),仍然用遠程圖片鏈接。
119             localImageSrc = remoteImageSrc;
120         }
121 
122     }

123 
124 
125     #endregion
126 
127     private WebClient clIEnt;
128 
129     /// <summary>
130     /// <see cref="System.Net.WebClIEnt"/>
131     /// </summary>
132     public WebClient ClIEnt
133     {
134         get
135         {
136             if ( clIEnt != null )
137             {
138                 return clIEnt;
139             }
140 
141             client = new WebClIEnt( );
142             client.Headers.Add( "user-agent" , "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2;)" );
143 
144             return clIEnt;
145 
146         }
147     }
148 
149     /// <summary>
150     /// 判斷Uri是否為本地路徑
151     /// </summary>
152     /// <param name="uri"></param>
153     /// <returns></returns>
154     private bool IsLocalSource( Uri uri )
155     {
156         for ( int i = localhost.Length ; --i >= 0 ; )
157         {
158             if ( localhost[ i ].ToLower( ) == uri.Host.ToLower( ) )
159             {
160                 return true;
161             }
162         }
163 
164         return false;
165 
166     }
167 
168     /// <summary>
169     /// 檢測文件類型是否為允許下載的文件類型
170     /// </summary>
171     /// <param name="extension">擴展名 eg: ".jpg"</param>
172     /// <returns></returns>
173     private bool IsAllowedDownloadFile( string extension )
174     {
175         for ( int i = allowImageExtension.Length ; --i >= 0 ; )
176         {
177             if ( allowImageExtension[ i ].ToLower( ) == extension.ToLower( ) )
178             {
179                 return true;
180             }
181         }
182 
183         return false;
184     }
185     
186 </script>
187 
188 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xHtml1-transitional.dtd">
189 <html XMLns="http://www.w3.org/1999/xHtml">
190 <head runat="server">
191     <title></title>
192     <style type="text/CSS">
193     body { margin: 0px; overflow: hidden;  background-color: buttonface;  }
194     td { font-size: 11pt; font-family: Arial;text-align: left;}
195     #domProgressBarId{
196         ;width: 0%;
197         height: 15px;  
198         border-right: buttonhighlight 1px solid;
199         border-top: buttonshadow 1px solid; 
200         border-left: buttonshadow 1px solid; 
201         border-bottom: buttonhighlight 1px solid;
202         background-color: highlight;

203     }
204 </style>
205 
206     <script type="text/Javascript" language="Javascript"> 
207         
208         var RemoteImageRubber = function ( remoteSrcList )
209         {
210             this._remoteSrcList = remoteSrcList;
211             this._totalFilesCount = remoteSrcList.length; 
212         }
213 
214         RemoteImageRubber.prototype.CurrentPercent = function()
215         {
216             return Math.round( 100 * (1-  this.CurrentFilesCount() / this.TotalFilesCount() ) )+"%";
217         }
218         
219         RemoteImageRubber.prototype.TotalFilesCount = function()
220         {
221             return this._totalFilesCount;
222         }
223         
224         RemoteImageRubber.prototype.CurrentFilesCount = function()
225         {
226             return this._remoteSrcList.length;
227         }
228 
229         RemoteImageRubber.prototype.NextFile = function ()
230         {
231            
232             if(this._remoteSrcList.length >0)
233             {
234                 var currentRemoteSrc = this._remoteSrcList.shift( )
235                 __PreCallServer(currentRemoteSrc);
236             }        
237         }
238         
239     </script>
240 
241     <script type="text/Javascript" language="Javascript">
242         
243         var oEditor;
244         var domProgressBar;
245         var domCurrentFile;
246         var domAllFilesCount;
247         var domAlreadyDownloadFilesCount;
248         
249         var imageUrls;
250         var remoteList = new Array();
251         var localList = new Array(); 
252         
253         var progressBar;
254         
255         function Ok()
256         {
257             var __imgIndex;
258             for(__imgIndex = 0; __imgIndex < imageUrls.length; __imgIndex ++)
259             {
260                 imageUrls[__imgIndex].src = localList[__imgIndex];    &nbsp;               
261             }    
262             
263             return true ;
264         }
265         
266     </script>
267 
268     <script language="Javascript" type="text/Javascript">
269     
270         function __PreCallServer(currentRemoteSrc)
271         {
272             var start = currentRemoteSrc.lastIndexOf("/") + 1;
273             var end = currentRemoteSrc.length - currentRemoteSrc.lastIndexOf("/");
274 
275             var currentFileName = currentRemoteSrc.substr(start,end);
276                         
277             domCurrentFile.innerHtml = currentFileName;         
278             __CallServerDownLoad(currentRemoteSrc,'');
279             
280         }

281         
282         function __ReceiveServerData(receiveValue ,context)
283         {
284             // 注意:-------------------------------------------------------------------------------------------
285             //
286             // (1)不要在接收回調數據時使用變量 "i"。
287             // (2)如果再次回調請使用window.setTimeout(.這樣的形式
288             //
289             //      否則會導致 "'__pendingCallbacks[].async' 為空或不是對象"的錯誤產生。
290             //  
291             //      因為MS的開發人員在WebForm_CallbackComplete函數內使用了全局變量"i" 。這是一個比較ugly的bug。
292             //
293             // 參見:
294             //   http://connect.microsoft.com/VisualStudio/feedback/VIEwFeedback.ASPx?FeedbackID=101974
295             //   http://developers.de/blogs/damir_dobric/archive/2006/03/02/4.ASPx?AJax_CallBack=true
296             //   http://developers.de/files/folders/279/download.ASPx
297             //   http://blogs.sqlXML.org/bryantlikes/archive/2005/12/20/4593.ASPx
298             //
299             //-------------------------------------------------------------------------------------------------
300 
301             if(receiveValue )
302             {
303                 var localSrc = receiveValue;
304                 localList.push(localSrc);
305                 
306                 domAlreadyDownloadFilesCount.innerHtml = progressBar.TotalFilesCount() - progressBar.CurrentFilesCount();
307                 domProgressBar.style.width = progressBar.CurrentPercent();
308                 
309                 if( progressBar.CurrentFilesCount() > 0 )
310                 {
311                    window.setTimeout("progressBar.NextFile()",0);        
312                 }
313             }            
314             
315             if(progressBar.CurrentFilesCount() == 0)
316             {                
317                 window.setTimeout("__reFlush()",500)
318             } 
319         }
320 
321         function __StartDownLoad()    
322         {   
323             imageUrls = oEditor.EditorDocument.body.getElementsByTagName("img");
324                 
325             var m; 
326             for(m = 0; m < imageUrls.length; m ++)
327             {
328                remoteList[m] = imageUrls[m].src;                      
329             }
330             
331             progressBar = new RemoteImageRubber(remoteList);              
332             domAllFilesCount.innerHtml = progressBar.TotalFilesCount();
333             
334             window.setTimeout("progressBar.NextFile()",0);
335             
336         }    
337 
338         function __reFlush()
339         {           
340             
341             domProgressBar.style.width  = "100%";
342             
343             //display the 'OK' button            
344             window.parent.SetOkButton( true ) ;
345         }
346         
347 
348     </script>
349 
350 </head>
351 <body>
352     <form id="ASPnetForm" runat="server">
353         <div >
354             <table border="0" cellspacing="0" cellpadding="2">
355                 <tr>
356                     <td nowrap="nowrap" >
357                         當前文件:&nbsp;<span id="domCurrentFile" ></span></td>
358                 </tr>
359                 <tr>
360                     <td >
361                         <div id="domProgressBarId">
362                         </div>
363                     </td>
364                 </tr>
365                 <tr>
366                     <td nowrap="nowrap" >
367                         共有:&nbsp;<span id="domAllFilesCount"></span>&nbsp;&nbsp;個文件</td>
368                 </tr>
369                 <tr>
370                     <td nowrap="nowrap" >
371                         已下載:&nbsp;<span id="domAlreadyDownloadFilesCount"></span>個。</td>
372                 </tr>
373             </table>
374         </div>
375     </form>

376 
377     <script type="text/Javascript" language="Javascript">
378     window.parent.SetOkButton( false ) ; 
379     
380     oEditor = window.parent.InnerDialogLoaded().FCK;       
381     
382     domProgressBar = document.getElementById("domProgressBarId");
383     domCurrentFile = document.getElementById("domCurrentFile");
384     domAllFilesCount = document.getElementById("domAllFilesCount");
385     domAlreadyDownloadFilesCount = document.getElementById("domAlreadyDownloadFilesCount");   
386 
387     window.setTimeout("__StartDownLoad()",0);  
388     </script>
389 
390 </body>
391 </Html>
392 


E:\IISROOT\FckTest\FckTest\fckeditor\editor\plugins\remoteimagerubber\fckplugin.JS


 1 FCKCommands.RegisterCommand(
 2     'RemoteImageRubber',
 3     new FCKDialogCommand( 'RemoteImageRubber', 
 4         FCKLang["RemoteImageRubberBtn"], 
 5         FCKPlugins.Items['remoteimagerubber'].Path + 'remoteimagerubber.ASPx', 
 6         350, 
 7         200 ) 
 8 ) ;
 9 var oBtn=new FCKToolbarButton('RemoteImageRubber',null,FCKLang["RemoteImageRubber"],null,false,true,48);
10 FCKToolbarItems.RegisterItem('RemoteImageRubber',oBtn);
11 

E:\IISROOT\FckTest\FckTest\fckeditor\editor\lang\zh-cn.JS(其他語言同樣)


1 var FCKLang =
2 {
3 //
4 RemoteImageRubberBtn:   "保存遠程圖片"
5 };


配置一下fckconfig.JS


 1FCKConfig.ToolbarSets["Default"] = [
 2    ['Source','DocProps','-','Save','NewPage','PrevIEw','-','Templates'],
 3    ['Cut','Copy','Paste','PasteText','PasteWord','-','Print','SpellCheck'],
 4 ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
 5    ['Form','Checkbox','Radio','TextField','Textarea','Select','Button','ImageButton','HiddenFIEld'],
 6    '/',
 7    ['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],
 8    ['OrderedList','UnorderedList','-','Outdent','Indent'],
 9    ['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
10    ['Link','Unlink','Anchor'],
11    ['Image','Flash','Table','Rule','Smiley','SpecialChar','PageBreak'],
12    '/',
13    ['Style','FontFormat','FontName','FontSize'],
14    ['TextColor','BGColor'],
15    ['FitWindow','-','InsertCode','RemoteImageRubber','-','About']
16] ; 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved