Kindeditor4.1.12添加远程文件本地化功能,远程图片自动上传

原创文章,转载请保留原文地址 http://www.56191.com/techarticle.asp?id=694

版本:version 4.1.12 (2019-03-07) 虽然没看过4.1.11的代码,但我感觉4.1.12可能还是有些改动的,因为网上一些其它修改教程,有时对不上代码。
(一)先来看看效果吧
1.先从网上复制一篇文章,里边含有其它网站上的远程图片
2.然后点击编辑器按钮,上传远程图片。

3.进程开始

4.完成

5.查看结果

(二)代码
1.增加按钮,修改kindeditor-all.js
271行
 'anchor', 'link', 'unlink', '|', 'uploadremotephoto', 'about'
6184行
uploadremotephoto : '远程文件抓取',
2.给按钮增加图标,修改editor\themes\default\default.css添加以下代码:
.ke-icon-uploadremotephoto {
    background: url("../common/uploadremotephoto.gif") no-repeat;
    color: #666;
    font-size: 14px;
    font-weight: bold;
    height: 16px;
    line-height: 16px;
    padding-left: 16px;
}
3.创建功能的前台部分,也就是插件

创建JS文件 \editor\plugins\uploadremotephoto\uploadremotephoto.js

KindEditor.plugin('uploadremotephoto', function(K) {
        var editor = this, name = 'uploadremotephoto';
        // 点击图标时执行
        editor.clickToolbar(name, function() {
var html = editor.html();
//alert(html);
//匹配图片(g表示匹配所有结果i表示区分大小写)
var imgReg = /<img.*?(?:>|\/>)/gi;
//匹配src属性
var srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i;
var arr = html.match(imgReg);
//alert('所有已成功匹配图片的数组:'+arr);

var dialog = K.dialog({
width : 500,
title : '<div id="ULRPTitle">远程文件抓取</div><div id="ULRPCurrent"></div><div id="ULRPTotal"></div>',
body : '<div style="margin:10px;"><select name="select" size="6" multiple id="seluploadphoto" style="width:100%"></select></div>',
closeBtn : {
name : '关闭',
click : function(e) {
dialog.remove();
}
},
yesBtn : {
name : '确定',
click : function(e) {
dialog.remove();
}
}
});
var ObjULRPCurrent=document.getElementById("ULRPCurrent");
var ObjULRPTotal=document.getElementById("ULRPTotal");
var ObjSelect=document.getElementById("seluploadphoto");
var OptionIndex=0;
if(arr){
for (var i = 0; i < arr.length; i++) {
var src = arr[i].match(srcReg);
//获取图片地址
if (src[1].indexOf("http://") >= 0 || src[1].indexOf("https://") >= 0){
//alert('已匹配的图片地址'+(i+1)+':'+src[1]);
var option=document.createElement("option");
option.text=src[1];
option.value=src[1];
option.setAttribute('OptionIndex',OptionIndex);
option.setAttribute('DealWithed',0);
ObjSelect.add(option,null);
OptionIndex++;
}
}
}
if (OptionIndex==0){
ObjULRPTotal.innerText=" 没有远程图片 ";
return false;
}else{
ObjULRPCurrent.innerText="0";
ObjULRPTotal.innerText=" / " + (OptionIndex-0);
}
//禁用一些按钮,略

var ArtTemporaryTimeIdForStorePhoto=document.getElementById("ArtTemporaryTimeIdForStorePhoto").value;
for(var i = 0 ; i<ObjSelect.options.length ;i++){
var CurrentPosition = ObjSelect.options[i];
if(CurrentPosition.getAttribute("DealWithed")==0){
var AjaxUrl="uploadremotephoto.asp";
var sendData = {
ArtTemporaryTimeIdForStorePhoto: ArtTemporaryTimeIdForStorePhoto,
RemotePhoto: CurrentPosition.value,
OptionIndex: CurrentPosition.getAttribute("OptionIndex"),
OperateType: 4
};
Ajax('get', AjaxUrl, sendData, DealWithResult, '')
}
}
//---------------------------------------------------------//
        });
});
function DealWithResult(result){
//alert(result);
var jsonObjKeyWOrds = JSON.parse(result);
//alert(jsonObjKeyWOrds[0].OptionIndex);
var ObjULRPCurrent=document.getElementById("ULRPCurrent");
var ObjULRPTotal=document.getElementById("ULRPTotal");
var ObjSelect=document.getElementById("seluploadphoto");
var html = editor.html();
CurrentOption = FindInProcess(ObjSelect,jsonObjKeyWOrds[0].OptionIndex);
CurrentOption.style.fontWeight = "bold";
ObjULRPCurrent.innerText=ObjULRPCurrent.innerText-0+1;

html=html.replace(CurrentOption.value,jsonObjKeyWOrds[0].LocalPath)
editor.html(html);
}
function FindInProcess(ObjSelect,OptionIndex){
for(var i = 0 ; i<ObjSelect.options.length ;i++){
var option = ObjSelect.options[i];
if(option.getAttribute("OptionIndex")==OptionIndex){
return option;
}
}
return null;
}


插曲:
这里需要用到AJAX,本想用Kindeditor自带的,但不知为什么,老是提示返回的json格式错误。
基于没用好Kindeditor的Ajax,就用了自己的Ajax.js

复制文章粘贴过来时,有时因HTML标签问题不能即时显示,要先切换到源码模式一次,再换回所见即所有模式就能显示了。 

4.后台页面调用Kindeditor

头部引用JS文件
<script charset="utf-8" src="../editor/kindeditor-all.js"></script>
<script charset="utf-8" src="../editor/lang/zh-CN.js"></script>
页面添加代码,初始化
写法可以
<script>
KindEditor.ready(function(K) {
window.editor = K.create('#TextContent');

var options = {
cssPath : '../techeditor/plugins/code/prettifyforadmin.css',
filterMode : true
};
var editor = K.create('textarea[name="content"]', options);
});
</script>
或者
KindEditor.ready(function (K) {
window.editor = K.create('#ArtContent', {
cssPath: '../techeditor/plugins/code/prettifyforadmin.css',
resizeType: 1,
allowPreviewEmoticons: false,
allowImageUpload: false
});
});
注意:
写到里边,不是写在外边。
../techeditor/plugins/code/prettifyforadmin.css,涉及代码高亮,以后会讲到。
页面增加元素,用来设定上传到哪个目录
        <input name="ArtTemporaryTimeIdForStorePhoto" type="text" id="ArtTemporaryTimeIdForStorePhoto" value="<%=EnCrypt(now())%>" size="30">
Form元素增加事件函数
 onSubmit="return CheckForm()"
function CheckForm(){
//这里是主要的,刷新HTML代码
editor.sync();

//顺便,判定表单内容是否为空,等等
</script>
ASP代码
Function EnCrypt(m) 
TempStr=m
TimeArray = Array("1","2","3","4","5","6","7","8","9","0", "/",":"," ","-")
AscArray = Array("A","B","C","D","E","F","G","H","I","O", "M","R","X","Z")
for ix=0 to Ubound(TimeArray)
TempStr=Replace(TempStr,TimeArray(ix),AscArray(ix))
next
EnCrypt=TempStr
End Function 
5.创建功能的后台部分,抓取远程图片,存储到本地,返回前台JSON数据 uploadremotephoto.asp。
<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<% Session.CodePage=65001
Response.Charset="UTF-8" %>
<%
'http://www.56191.com/techadmin/uploadremotephoto.asp?ArtTemporaryTimeIdForStorePhoto=BOBOMCMDXIREARCA&RemotePhoto=https://imgs.ali213.net/news/2020/03/04/2020030451427859.jpg
'http://www.56191.com/techadmin/uploadremotephoto.asp?ArtTemporaryTimeIdForStorePhoto=BOBOMCMDXIREARCA&RemotePhoto=https://img-blog.csdn.net/20160530170111690

'图片目录【可设置】
ManualPortfolio="\UploadFiles\Manual"

'这篇文章的图片目录名
ArtTemporaryTimeIdForStorePhoto=Request("ArtTemporaryTimeIdForStorePhoto")
'远程图片地址URL
RemotePhoto=Request("RemotePhoto")
'图片列表索引
OptionIndex=Request("OptionIndex")

'给出上传后的文件名
sSaveFilePath=ManualPortfolio&"\"&ArtTemporaryTimeIdForStorePhoto&"\"

arrSaveFileName = Split(RemotePhoto,".")
SaveFileType = arrSaveFileName(UBound(arrSaveFileName))
if len(SaveFileType)>5 then
SaveFileType="SaveFileTypeNeedCatch"
end if

Randomize
RanNum = Int(900*Rnd) + 100
arrSaveFileName = Month(Now()) & Day(Now())& Hour(Now()) & Minute(Now()) & Second(Now())
arrSaveFileName = arrSaveFileName & ranNum & "." & SaveFileType
SaveFileName = sSaveFilePath & arrSaveFileName

SimulateUserAgent="Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.56191.com)"

'生成目录,准备抓取
Call MakeFolder (ManualPortfolio,ArtTemporaryTimeIdForStorePhoto)

LocalFileName=SaveFileName

if SaveRemoteFile(SaveFileName,RemotePhoto) then
response.write "[{"
response.write """Result"":0,"
response.write """OptionIndex"":"&OptionIndex&","
response.write """LocalPath"":"&""""&Replace(LocalFileName,"\","/")&""""
response.write "}]"
else
response.write "[{"
response.write """Result"":1,"
response.write """OptionIndex"":"&OptionIndex&","
response.write """LocalPath"":"&""""&Replace(LocalFileName,"\","/")&""""
response.write "}]"
end if

Function SaveRemoteFile(s_LocalFileName,s_RemoteFileUrl)
Dim Ads
Dim Retrieval
Dim GetRemoteData
'On Error Resume Next
Set Retrieval = server.createobject("WinHttp" & "." & "WinHttpRequest" & "." & "5" & "." & "1")
lresolveTimeout = 10000 ' 解析DNS名字的超时时间,10秒
lconnectTimeout = 10000 ' 建立Winsock连接的超时时间,10秒
lsendTimeout    = 10000 ' 发送数据的超时时间,12秒
lreceiveTimeout = 10000 ' 接收response的超时时间,20秒
Retrieval.setTimeouts CLng(lresolveTimeout),CLng(lconnectTimeout),CLng(lsendTimeout),CLng(lreceiveTimeout)
'Retrieval.OPTION(6)=false

TargetUrlT=s_RemoteFileUrl
TargetUrlT=replace(TargetUrlT,"&amp;","&")
HostArr=split(TargetUrlT,"/")
Host=HostArr(2)
RefUrlT=HostArr(0)&"/"&HostArr(1)&"/"&HostArr(2)

'response.write "<br><textarea cols=""121"" rows=""15"">"
'response.write "<>您的提交信息如下:"&vbcrlf
'response.write "<>s_LocalFileName:"&s_LocalFileName&vbcrlf
'response.write "<>s_RemoteFileUrl:"&s_RemoteFileUrl&vbcrlf
'response.write "<>TargetUrlT:"&TargetUrlT&vbcrlf
'response.write "<>Host:"&Host&vbcrlf
'response.write "<>RefUrlT:"&RefUrlT&vbcrlf
'response.write  "</textarea><br>"&vbcrlf

With Retrieval
.Open "GET", TargetUrlT, False
.setRequestHeader "Accept","*/*"
if RefUrlT<>"" then
.setRequestHeader "Referer",RefUrlT
end if
.setRequestHeader "Accept-Language","zh-cn"
.setRequestHeader "User-Agent", SimulateUserAgent
.setRequestHeader "Host",Host
.setRequestHeader "Connection","Keep-Alive"
if CookieStr<>"" then .setRequestHeader "Cookie",CookieStr
.Send()
If Err.number<>0 then
SaveRemoteFile = False
Exit Function
End If
If .Status > 300  then
Set Retrieval = Nothing 
SaveRemoteFile = False
Exit function
End if
GetRemoteData = .responseBody
End With
if instr(s_LocalFileName,"SaveFileTypeNeedCatch")>0 then
ContentTypeStr = Retrieval.getResponseHeader("Content-Type")
select case ContentTypeStr
 case "image/gif"
   RealSuffix = "gif"
 case "image/jpeg"
   RealSuffix = "jpg"
 case "image/png"
   RealSuffix = "png"
 case "image/webp"
   RealSuffix = "png"
 case else 
  RealSuffix = "XXX"
end select
s_LocalFileName=Replace(s_LocalFileName,"SaveFileTypeNeedCatch",RealSuffix)
LocalFileName=Replace(LocalFileName,"SaveFileTypeNeedCatch",RealSuffix)
end if
Set Retrieval = Nothing

Set Ads = Server.CreateObject("Ado" & "db.Str" & "eam")
With Ads
.Type = 1
.Open
.Write GetRemoteData
.SaveToFile Server.MapPath(s_LocalFileName), 2
.Cancel()
.Close()
End With
Set Ads = Nothing
If Err <> 0 Then
SaveRemoteFile = False
Err.Clear
Else
SaveRemoteFile = True
End If
End Function

'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'函数:创建文件夹
'RootPath 起始目录,从这里开始向下创建。通常为站点图片目录或图片目录设的虚拟目录,从URL的域名后边开始也就是从站点根目录开始。如,/Resource/Photos/
'UrlStr   需要创建的部分,不是站点开通时就有的那部分
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Function MakeFolder (RootPath,UrlStr)
'创建文件对象,准备写入
'on error resume next
PurePath=Replace(Replace(UrlStr,"/","\"),RootPath,"")
UrlArr=Split(PurePath,"\")
set fso=Server.CreateObject("Scripting.FileSystemObject")
Root=Server.mappath(RootPath)
CurrFolder=Root
for i=0 to UBound(UrlArr)
CurrFolder=CurrFolder&"/"&UrlArr(i)
CurrFolder=Replace(CurrFolder,"/","\")

If Not fso.FolderExists(CurrFolder) Then
fso.CreateFolder(CurrFolder)
End If
next
End Function
%>

 要求返回格式如下:
[{"Result":0,"OptionIndex":,"LocalPath":"/UploadFiles/Manual/BOBOMCMDXIREARCA/20200307190425937.jpg"}]
到这里就全实现了,已解决。下次讲讲Kindeditor添加代码高亮功能。