一、数据同步原理
假设A、B两个系统要实现会员数据同步,同步过程是这样的:当A系统要注册(登录/注销/资料修改/删除用户)时,就发一条消息告诉B系统说,我要注册(登录/注销/资料修改/删除用户)了,B系统收到消息后在其系统内进行注册(登录/注销/资料修改/删除用户),完成后返回一条消息告诉A系统执行的结果(成功/失败),如果成功,A系统继续在其系统内进行注册(登录/注销/资料修改/删除用户)操作,如果失败则中止本次操作,反之亦然。
1.数据格式
现在我们引进两个词语:请求和响应,对于上述过程中发出消息我们称它为请求,返回消息我们称它为响应。对于请求和响应的数据格式,PDO是有规定的,它应是一个构造良好的xml文档。标准的请求和响应数据格式如下:
<?xml version="1.0" encoding="gb2312"?>
<root>
<appid>[i]程序标识[/i]</appid>
<action>[i]请求类型(用户名检测/注册/登录/注销/资料修改/删除用户)[/i]</action>
<syskey>[i]安全码[/i]</syskey>
<username>[i]用户名[/i]</username>
<[i]可选元素列表[/i] />
</root><?xml version="1.0" encoding="gb2312"?>
<root>
<appid>[i]程序标识[/i]</appid>
<status>[i]请求结果[/i]</status>
<needcookie>[i]是否需要写cookie[/i]</needcookie>
<body>
<message>[i]操作不成功时的错误说明[/i]</message>
<[i]可选元素列表[/i] />
</body>
</root>在请求的XML文档中有些节点是必需的,有些节点是可选的,必需的节点总结如下:
1.注册(reguser):appid,action,syskey,username,password,email,question,answer
2.登录(login):appid,action,syskey,username
3.注销(logout):appid,action,syskey,username
4.资料修改(update):appid,action,syskey,username
5.删除用户(delete):appid,action,syskey,username
6.注册时检测用户名是否可用(checkname):appid,action,syskey,username
在响应的XML文档中有三个节点是必需的:appid,status,message
2.数据如何传递?
对于请求,将使用XMLHttpRequest对象的Send方法以post方式发送,然后再从XMLHttpRequest对象的responseXML属性中获取响应数据。
3.接口安全码
接口安全码(syskey节点)是用来检验程序间传输的数据来源合法性的依据,它的值是由username节点的值和各程序接口配置文件中用户定义的密钥连接起来,再进行16位MD5加密得出一个定长32字节的字符串。
二、动网实现PDO1.0
从第一节的原理中我们可以知道,要支持数据同步,那么每个系统中都必须有请求和响应的程序,这样才能向其他系统发出请求和响应其他系统发出的请求。
对于请求,动网中包含有一个类DvApi,它位于dv_dpo\Cls_DvApi.asp,在各种请求中都使用该类生成请求的XML文档并发送和获取响应值,下边是修改资料的请求:
'-----------------------------------------------------------------
'系统整合:更新资料(update)
'-----------------------------------------------------------------
Dim DvApi_Obj,DvApi_SaveCookie,SysKey
If DvApi_Enable Then
Set DvApi_Obj = New DvApi
DvApi_Obj.NodeValue "syskey",SysKey,0,False
DvApi_Obj.NodeValue "action","[color=Red]update[/color]",0,False
DvApi_Obj.NodeValue "username",txtUserName,1,False
Md5OLD = 1
SysKey = Md5(DvApi_Obj.XmlNode("username")&DvApi_SysKey,16)
Md5OLD = 0
DvApi_Obj.NodeValue "syskey",SysKey,0,False
DvApi_Obj.NodeValue "password",txtUserPass,1,False
DvApi_Obj.NodeValue "email",txtEmail,1,False
DvApi_Obj.NodeValue "answer",txtQuestion,1,False
DvApi_Obj.NodeValue "question",txtAnswer,1,False
DvApi_Obj.SendHttpData
If DvApi_Obj.Status = "1" Then
Response.write("<script>alert(""" & DvApi_Obj.Message & """);history.go(-1);</script>")
Response.End()
End If
Set DvApi_Obj = Nothing
End If
'-----------------------------------------------------------------
和请求相关的文件还有:dv_dpo\api_user.xml(XML模板)和dv_dpo\Api_Config.asp(接口配置文件)。
对于所有的请求(响应)动网都集中在一个文件中进行处理:dv_dpo.asp,该文件的结构为:
<%
If Request.QueryString<>"" Then
'处理登录和注销请求,参数以调用外部JS的方式发送([color=Red]A[/color])
Else
Set XmlDoc = Server.CreateObject("msxml2.FreeThreadedDOMDocument" & MsxmlVersion)
XmlDoc.ASYNC = False
If Not XmlDoc.LOAD(Request) Then
Status = 1
Messenge = "数据非法,操作中止!"
appid = "未知"
Else
If CheckPost() Then
Select Case Act
Case "checkname"
'处理用户名检测请求
Case "reguser"
'处理注册请求
Case "login"
'处理登录请求([color=Red]B[/color])
Case "logout"
'处理注销请求([color=Red]C[/color])
Case "update"
'处理更新请求
Case "delete"
'处理删除用户请求
End Select
End If
End If
ReponseData()'生成响应XML文档
Set XmlDoc = Nothing
End If
%>通常情况下B、C直接返回status=0(成功)即可,真正的登录和注销操作应在A处,之所以这样主要是由于XMLHttpRequest对象与服务器的会话方式决定的(见参考文章)。
三、个人网站整合过程
1.下载动网8.0/8.1版,解压到站点bbs文件内;
8.0版下载:http://down.dvbbs.net/new_Softview/SoftView_5421.asp
8.1版下载:http://forum.dvbbs.net/download/dvbbs8.1.0_ac.exe
2.将动网dv_dpo文件夹和dv_dpo.asp文件复制到站点根目录中,并进行以下修改:
① dv_dpo\Cls_DvApi.asp:
a. 修改AppID的值,如"Mzwu"
b. 全部Dvbbs.iCreateObject改为Server.CreateObject
② dv_dpo\Api_Config.asp:
a. 将DvApi_Enable值修改为True
b. 修改DvApi_SysKey的值,不能用默认的"API_TEST",如"API_MZWU"
c. DvApi_Urls的值修改为论坛dv_dpo.asp地址,如"http://localhost/test/bbs/dv_dpo.asp"
③ dv_dpo.asp:
a. 修改XmlDoc.documentElement.selectSingleNode("appid").text的值,一般是和Cls_DvApi.asp中的AppID相同的值。
b. 修改注册/登录/注销/资料修改/删除用户相关函数。
3.修改动网接口配置文件(dv_dpo\Api_Config.asp)中相关参数:
a. 将DvApi_Enable值修改为True
b. 修改DvApi_SysKey的值,不能用默认的"API_TEST",如"API_MZWU"
c. DvApi_Urls的值修改为其他系统dv_dpo.asp地址,如"http://localhost/test/dv_dpo.asp"
4.下边提供一个我已经整合好的一个会员系统(只需将两系统DvApi_Enable值修改为True即可使用):点击下载
注:如若是整合动网,动易,oblog三系统可用动易小李刀刀的API整合专用用户数据同步工具,下载地址:http://www.powereasy.net/Soft/PE_Plus/210.html
四、注意事项
问:为什么在登录和注销时不能使用Response.Redirect进行跳转?
答:在登录和注销成功时需构造一个script脚本输出到页面进行真正的登录或注销,如果使用Response.Redirect会导致script不能输出到页面,结果就是当前系统能成功登录或注销,其他系统却不行,也没报错。
问:整合的系统数目多少个最合适?
答:2个。假设我们按要求成功的整合了A、B、C三个系统,现在A中开始注册,A就要向B和C两个系统发送请求说要注册,假设B系统是正常的并注册成功了(用户信息写入B数据库中),再假设C系统突然出问题了不能成功注册,那么返回的值就是失败的(Status = "1"),结果是A系统也不再继续注册了,但B系统中新加的用户信息却是不能撤销的!当整合的系统数不小于3时都可能出现上述的问题,所以整合数目为2是最佳的!
问:生成请求XML文档的节点时,DvApi_Obj.NodeValue "username",username,1,False和DvApi_Obj.NodeValue "username",username,0,False有什么区别?
答:没有区别。当用1时生成的节点为"<username><![CDATA[admin]]></username>",当用0时生成的节点为"<username>admin</username>"。也就是说,当节点的内容比较多时,最好采用1,比较少时采用0,结果都能被正常获取的!
五、事例过程中常见错误
1.提示"请求数据错误"
答:检查配置文件Api_Config.asp中接口文件地址是否正确(DvApi_Urls的值)!
2.提示"默认非法请求"
答:出于安全考虑,系统密钥的值不能采用默认的"API_TEST"或"Syskey",请检查配置文件Api_Config.asp中DvApi_SysKey的值。
3.提示"请求数据验证不通过,请与管理员联系"
答:各系统MD5加密的结果不一样,可先从位数上检查(MD5有16位和32位加密),再检查各系统MD5函数对同一字符串加密的结果是否相同(有一次我就发现竟然不同的:(),最后再检查下是否由于大小写的原因。
4.没有出错,但一个系统能操作(登录/注销)成功,其他系统都没操作成功(没同步)
答:检查构造script脚本是否有输出到页面上,即第四节注意事项第1问的内容。
六、参考文章
1.PDO通行接口开发人员参考规范1.0:http://www.mzwu.com/pic/20070817/pdo.htm
2.解读动网、Oblog、动易三方制订的PDO通行接口:http://www.mzwu.com/article.asp?id=1035
3.说说serverXMLHTTP对象与服务器的会话方式:http://www.mzwu.com/article.asp?id=1039
-------------------------------------------------------------------
修改记录:
2008-01-16 在论坛中修改资料不成功,提示请填写用户名或密码。感谢BB仔(QQ:100138328)提出。
2008-01-23 在论坛中用存在的用户名注册时,其他系统注册成功(两个用户一样用户名),而论坛未注册成功。感谢(决情/tx)(QQ:124529585)参与测试。
2008-06-09 在Dvbbs8.2中注册不成功。原因是8.2在注册时不要求必填密码问题和密码答案,而会员系统按"DPO通行接口开发人员参考规范"开发,在规范的3.2节中说明这两项是必填项目,才导致注册不成功。修改方法:修改会员系统dv_dpo.asp文件的Reguser函数,将:
If UserName="" or UserPass="" or Question="" or Answer="" Then
Status = 1
Messenge = Messenge & "<li>请填写用户名或密码。"
Exit Sub
End If修改为:
If UserName="" or UserPass="" Then
Status = 1
Messenge = Messenge & "<li>请填写用户名或密码。"
Exit Sub
End If
评论(8)
暂时新下载路径为:http://www.mzwu.com/picnew/20071220/test.rar
今天会全部调试完毕!
例子是肯定可以的,我在本地都测试过的
哪个地址不能下?
怎么试的?具体什么不成功?错误吗?有什么提示?