自动保存草稿功能的原理
我们都知道网页是一种无状态的,每次都需要请求,响应,当一次请求完成后就与服务器断开连接了,所以我们不能像网页一样实现实时的交互功能,但是为了满足更多的需求一个比较无敌的程序员还是想到了实时交互的办法,所以ajax诞生了,这项技术最先应用于google地图,后来逐渐被大众化,所谓ajax其实是一项异步请求技术,简单来理解就是我们在看页面的时候当页面的内容发生了改变,我们不需要刷新页面,而是通过后台程序向服务器发送这个请求,然后再把响应结果悄无声息的展现在页面上,那么我们自动存稿的功能就很好理解了,在我们往编辑器里写内容的时候我们的后台程序会定时把内容发布到服务器上保存起来,然后等我们的文章写完发布之后如果发布成功了则把之前保存的草稿删除掉,如果没有保存成功则不删除等用户下次打开发布页面的时候把保存的草稿重新加载给用户,这样我们就完成了类似于word里面自动保存的功能了。
具体功能实现
第一步:我们需要创建一个ajax所需要的js对象,这个创建方法网上有很多代码,我也是随便找了一个拿来用,代码如下:
// AJAX类
function AJAXRequest() {
var xmlObj = false;
var CBfunc,ObjSelf;
ObjSelf=this;
try { xmlObj=new XMLHttpRequest; }
catch(e) {
try { xmlObj=new ActiveXObject("MSXML2.XMLHTTP"); }
catch(e2) {
try { xmlObj=new ActiveXObject("Microsoft.XMLHTTP"); }
catch(e3) { xmlObj=false; }
}
}
if (!xmlObj) return false;
this.method="POST";
this.url;
this.async=true;
this.content="";
this.callback=function(cbobj) {return;}
this.send=function() {
if(!this.method||!this.url||!this.async) return false;
xmlObj.open (this.method, this.url, this.async);
if(this.method=="POST") xmlObj.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlObj.onreadystatechange=function() {
if(xmlObj.readyState==4) {
if(xmlObj.status==200) {
ObjSelf.callback(xmlObj);
}
}
}
if(this.method=="POST") xmlObj.send(this.content);
else xmlObj.send(null);
}
}
把这些代码复制下来放到一个js文件里,我们取名:ajaxrequest.js
接下来我们需要在页面需要保存草稿的地方加一个提示,每次存稿需要提醒用户保存成功了,我们在编辑器的边上放上一个div就可以了<div id="AutoSaveMsg"></div>,一会儿我们通过js,动态的把提示消息写入到这个div里,就完成了自动提示的功能。
第二步:编写保存草稿的程序代码
这个功能也很好实现,新建一个页面,取名:autosave.asp,然后写上如下代码:
<%
Dim PostContent,action,objStream
''获取操作,是保存草稿还是恢复草稿
action=Request.Form("action")
''获取草稿内容
PostContent=Request.Form("postcontent")
IF action="restore" Then
''使用 ADODB.Stream 来进行文件操作
Set objStream = Server.CreateObject("ADODB.Stream")
With objStream
.Type = 2
.Mode = 3
.Open
''文件名为 autosave.txt
.LoadFromFile(Server.MapPath("autosave/autosave.txt"))
.Charset = "gb2312"
''.Position = 0
PostContent = .ReadText()
.Close
End With
Set objStream = NoThing
''输出草稿
IF PostContent<>"" Then Response.Write(PostContent)
Else
''保存草稿,如果草稿内容不为空则进行保存操作
IF PostContent<>Empty Then
''使用 ADODB.Stream 来进行文件操作
Set objStream = Server.CreateObject("ADODB.Stream")
With objStream
.Type = 2
.Mode = 3
.Open
.Charset = "utf-8"
.Position = objStream.Size
.WriteText= PostContent
.SaveToFile Server.MapPath("autosave/autosave.txt"),2
.Close
End With
Set objStream = NoThing
''输出保存是否成功信息
If Err.Number=0 then
Response.Write("<font style=""font-size:12px;color:green;"">"&Now()&" AutoSave success!</font>")
Else
Response.Write("<font style=""font-size:12px;color:red;"">"&Now()&" Auto-Save failed,errorNo:"&Err.Number&",error message:"&Err.Dscription&"</font>")
End If
End IF
End IF
%>
这段代码很简单,但是为了方便不懂asp的朋友我还是简单的说一下:
首先定义了两个变量,一个是action,这个是保存状态的,需要判断我们是保存草稿,还是读取草稿,这个原理就像是添加修改文章一样,PostContent=Request.Form("postcontent") 这句代码是获取需要保存的内容,我们的if语句判断是第一种情况则是读取文件,把txt里的内容读取出来输出到页面上,而else则是保存草稿,当我们保存成功之后我们把时间和是否保存成功的消息写到页面上,然后用js来读取这个页面的信息,我们就完成异步操作了。
OK,下一步我们需要建立一个js文件:
第三步:创建处理的js文件
创建一个js文件,取名为:autosave.js然后把如下代码复制进去:
// 要保存的内容对象FormContent
var FormContent=document.getElementById("TxtContents");
// 显示返回信息的对象
var AutoSaveMsg=document.getElementById("AutoSaveMsg");
// 自动保存时间间隔
var AutoSaveTime=60000;
// 计时器对象
var AutoSaveTimer;
// 首先设置一次自动保存状态
SetAutoSave();
// 自动保存函数
function AutoSave()
{
// 如果内容为空,则不进行处理,直接返回
if(!FormContent.value) return;
// 创建AJAXRequest对象,
var ajaxobj=new AJAXRequest;
ajaxobj.url="autosave.asp";
ajaxobj.content="postcontent="+escape(FormContent.value);
ajaxobj.callback=function(xmlObj)
{
// 显示反馈信息
AutoSaveMsg.innerHTML=xmlObj.responseText;
}
ajaxobj.send();
}
// 设置自动保存状态函数
function SetAutoSave()
{
AutoSaveTimer=setInterval("AutoSave()",AutoSaveTime);
}
// 恢复最后保存的草稿
function AutoSaveRestore()
{
// 创建AJAXRequest对象
var ajaxobj=new AJAXRequest;
// 提示用户正在恢复
AutoSaveMsg.innerHTML="正在恢复,请稍候……"
ajaxobj.url="autosave.asp";
ajaxobj.content="action=restore";
ajaxobj.callback=function(xmlObj)
{
// 提示用户恢复成功
AutoSaveMsg.innerHTML="恢复最后保存成功";
// 如果内容为空则不改写textarea的内容
if(xmlObj.responseText!="")
{
// 恢复草稿
FormContent.value=xmlObj.responseText;
}
}
ajaxobj.send()
}
代码讲解:
首先创建了两个对象用来得到需要保存的信息和返回信息的对象,第二个autosavemsg存储的是那个div 的对象,在下面AutoSaveMsg.innerHTML="正在恢复,请稍候……" 这个时候用到的。
然后定义的是时间间隔,以及具体的实现方法,第一次我们需要让他自动先保存一下,然后就会一直按我们的时候不停的保存了,至于为什么这样做,你可以去查一下setInterval这个函数的用法,网上有很不错的介绍。
SetAutoSave() 方法是用来自动保存的,没有什么好说的
AutoSave() 这个方法是用来自动保存草稿的,首先建立了之前我们保存的那个ajax对象,所以我们用的时候需要把这些代码合并到一起,所以我们需要在页面上建立两个引用,代码如下:
<!-- 将JS代码放在所有对象之后,以免在页面未加载完成时出现对象不存在的错误 -->
<!-- AJAX类 -->
<script type="text/javascript" src="TianDaoEdit/ajaxrequest.js"></script>
<!-- 自动保存代码 -->
<script type="text/javascript" src="TianDaoEdit/autosave.js"></script>
在需要自动存稿的地方把这两句引用加上,这里面的js对象就全部成公用的了,所以在函数里我们用var ajaxobj=new AJAXRequest;实例化上面那个js里的对象就不会有问题了,然后就是设置几个参数,ajaxobj.url="autosave.asp"; 这个文件是刚才我们编写的asp处理程序,也就是ajax需要请求的页面地址,你可以改成你喜欢的名字,ajaxobj.content="postcontent="+escape(FormContent.value);这句是向上面的地址发送的参数,escape是一个加密函数,直接这样用就可以了。
再下面就是得到返回信息写到页面上那个提示的div里AutoSaveMsg.innerHTML=xmlObj.responseText;
这样我们自动存稿功能就算是完成了。
看那个提示:2010-7-21 12:51:44 AutoSave success! 然后再去ftp上看看,有一个文件,下载下来看看是自己的草稿,保存成功了。提示语你可以改成汉字的,我最近在练英语,自己知道的单词在编程的时候喜欢写英文,呵呵。
AutoSaveRestore() 这个函数是恢复保存的草稿,功能和上面的类似,只不过返回的信息写入到了FormContent.value=xmlObj.responseText;这个里,而FormContent这个对象是你页面上编辑器的那个input,所以就把保存的内容写到这里面来了,这样我们就把保存的信息给恢复了。
注意问题:
如果你的编辑器是一个iframe编辑器,则input的value取值方法需要变一下了
function Autogetinfo()
{
document.form1.TxtContents.value = frames.message.document.body.innerHTML;
}
setInterval("Autogetinfo()",1000);
这是我的代码,你可以拿去直接用,我把iframe里的信息每隔一秒就赋值给那个input控件,则后面取值直接取input这个控件里的值就没有问题了,而后面是每一分钟自动保存一次,那个值可以自己设置的,以毫秒为单位,一秒等于1000毫秒,自己算吧。
第二个需要注意的问题就是在你发布成功的时候记得把草稿删除了,免得下次加载的时候还出来或和之前保存的冲突,这个用程序实现很简单,在你发布成功的时候判断一下就可以了,我的代码如下:
''--删除自动存稿--
set fso = createobject("scripting.filesystemobject")
dim filename1
filename1=server.mappath("autosave.txt")
If fso.FileExists(filename1) Then
fso.deletefile(filename1)
end if
set fso = nothing
''--删除自动存稿--
我是用asp做的,如果你用C#写的话就一句代码就可以搞定,File.Delete就可以了
而当页面加载的时候还需要去判断一下草稿是否存在,如果存在的话则需要读出数据,我的方法如下:
Function ReadTxt(TxtPath)
Set objStream = CreateObject("adodb.stream")
EditFile=TxtPath
objStream.Type=2
objStream.Mode = 3
objStream.Charset = "utf-8" ''可以改成gb2312
objStream.Open
objStream.LoadFromFile Server.MapPath(EditFile)
ReadTxt = objStream.ReadText
objStream.Close
Set objStream = Nothing
End Function
''--检测草稿箱里是否有未发布的草稿--
filepath="autosave.txt"
content=""
Set fs = CreateObject("Scripting.FileSystemObject")
if fs.fileExists(Server.Mappath(filepath)) then
content=ReadTxt(filepath)
end if
判断如果草稿存在,则把草稿里的信息读取出来,放到content里,然后加载到编辑器里就行了。
总结:
为了写这篇文章我到现在还没有吃中午饭,呵呵,如果感觉这篇文章帮助到了你,不要忘了留言说声谢谢,有支持才有动力嘛,好了,如果在实现功能的时候遇到问题也可以留言咨询影子。