摘要:网页中嵌入本网站外提供的服务,需要在网页文件中插入服务引擎代码,而其它的大量JAVASCRIPT要执行的代码都要在页面解析时通过JS插件或动态请求下载,要在解析器线程内执行属不同域的服务代码[1] 。自动化代码插入保证使用站外服务方便可靠,避免插入代码引起网页文件破坏。
关键词:引擎代码;JS插件;代码插入;站外服务
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2014)36-8650-03
网页是当今企业的宣传的重要窗口,现很多公司通过网页“面对面”和客户直接聊天,提高了业务的成功率。把本站外聊天系统和网页融合是大多数公司的首选,特别是中小型公司。提供系统服务公司在保证客户现有网页原来功能和信息不会破坏的情况下,如何把聊天功能嵌入到客户各网页中,该文就此问题提供了一个现实可行的解决方案。
1 系统功能介绍
系统涉及服务提供商、请求服务的客户、客户网页浏览者的三种角色。客户向服务提供商申请网页聊天服务,首先要在服务商注册公司服务账号,登记账号管理员和业务咨询人员,并对咨询人员进行分类记,随后客户可使用工具把服务商提供的网页代码插入本公司页面。当浏览者访问客户网页时服务商嵌入客户网页的聊天请求界面会增强呈现在浏览者的面前,浏览者点击后,客户的工作人员就可以使用桌面聊天程序和浏览者(在网页中)聊天,聊天的信息通过服务商传递到双方。
2 插入的页面代码功能设计
2.1 代码插入的工作原理
由于要执行的代码量比较大,在页面中插入的代码只是关键的引擎代码,否者对原页面维护会带来破坏和混乱,由此需要通过JS插件方式,大量的代码在网页解析时才下载到页面。在执行插入的JAVASCRIPT代码时,可以生成新的DOM JS插件对象,当浏览器解释新JS插件对象时又下载执行另一JAVASCIPT代码。通过这种方式把所有代码分次下载到浏览器中,最终聊天请求提示界面和的页面无缝融合在一起显示,成为页面整体中的一部分。
2.2 插入的提示代码设计
为了维护原页面文件方便,在页面显示时不会影响原页面内容显示的顺序,减少浏览器执行擦入代码时触发DOM的重解析,因此插入代码的最好位置是页面的最后面,也就是紧靠前。插入的代码应考虑未来服务的迁移性、客户账号和服务站点的不同性、代码块标识的唯一性。插入的代码范例如下:
<!— BEGIN{www.szyhpx.com} —> // 代码块标识
//‘szyhpx是服务站点的标识,具体的域名在 szyhpx.js文件中定义
// 具体变量名为webAdr
// 定义网页访问轨迹函数
// 客服请求服务注册名
var cmpyId='NCCDPX';
// 定义提供服务的站点名
var webWSId='szyhpx';
//由其它页面进入本页面
var priorPage=escape(document.referrer);
var url=escape(document.URL);
var series= readCookie("series");
// 使用servlet 方式动态生成Javascript,然后浏览器执行代码
document.write('');
<!— END{www.szyhpx.com} —>
以上代码中服务站点名和具体站点地址(域名)的分离保证了系统部署的灵活性,使提供的服务可任意迁移。代码中也定义了访问网页的轨迹,为后台提供了分析浏览者的访问行为、感兴趣网页的数据。
2.3 代码引擎Servlet设计
聊天提示界面中包含了客户业务服务部门,服务人员等有关信息,这些信息都是放在数据库中,Servlet要把这些信息转化成JAVASCRIPT 的变量形式,以便javascript能利用这些变量值。转化形式有二类:一是单一变量,如生成客户注册号cmpId变量out.println("var cmpyId=\""+cmpyId+"\";\n");二是数组变量如定义部门变量dept并初始化String divAry=" var dept=new Array();\n"; for(int i=0;lst!=null&& i { initStr+= "dept["+ i +"]=\"" +lst.get(i).getDivisionClass() "\";\n" ; } 。 对于JAVASCRIPT函数库文件,还是通过浏览器在解析时下载,因此就不用out 对象调用Print 和write的方法动态生成,而要使浏览器执行JAVSCRIPT时又触发下载JS插件,要在JAVASCRIPT中调用DOCUMENT的write的方法。当有多个JS插件库下载时,out.write 顺序要符合JAVASCRIPT执行代码调用顺序[2] 。在系统中使用了JQuery插件库和生成界面库displayservants.js开发库,实现浏览器下载JS插件的代码如下,
ws="";
out.write(" document.writeln('"+ws+"');" );
ws="";
out.write(" document.writeln('"+ws+"');" );
ws="";
out.write(" document.writeln('"+ws+"');" );
ws="";
out.write(" document.writeln('"+ws+"');" );
由于客户网页采用的字符集和JS插件不同,可在浏览器在下载时时要指明JS插件所用的字符集,为了保持生成的代码字符串和JS插件代码字符集一致,在SERVLET要使用response 对象中setCharacterEncoding 的方法设置输出内容的字符集(GBK),否则会导致界面乱码情况。
2.4 聊天提示界面呈现
在生成界面时会涉及大量的字符串合并(+)操作,这种操作效率比较低,应采用数组方式进行字符串合并[3] .显示提示界面的目的就是提醒浏览者和客户业务人员建立会话,以及提供简约的广告,但这界面不能影响浏览者的正常浏览。界面显示方式一般有二种,漂浮式和弹出式,漂浮式根据浏览者查看网页上下移动而移动,通常在屏幕左右二侧并且不宜过大;弹出式是隔一段时间显示界面在屏幕中央,可随时隐藏,二种界面采用层和绝对位置方式实现。界面显示的绝对位置由浏览器二个变量决定,窗口滚动的偏移(document.body.scrollTop/Left)和所处当前窗口的偏移,窗口偏移位置对于漂浮式是鼠标事件的坐标(event.clientX/Y),弹出式是根据界面窗口和浏览器窗口大小算出。浮漂式浏览者可直接选择具体的业务人员聊天,而弹出式则是想根据浏览者选择的业务部门,然后由系统根据某种原则指派一位业务人员。漂浮式要显示客户业务部门和所属部门的业务人员,在建立界面时采用多层次表格方式,如要显示的部门和人员比较多时不适合采用此界面,而应采用弹出式界面。二种界面的示意图如下,左图为漂浮式右图为弹出式。
图1 聊天提示界面
在漂浮是提示界面中,需要显示业务人员的在线状态,并要不断刷新。在线状态数据和网页通常不在同一域,这就涉及了跨域异步安全访问问题,直接在浏览器Timer中不能访问不同域。为了减少复杂性在漂浮式界面中只显示在线的”初始“状态,由浏览者操作刷新在线状态,刷新单个或所有。基于业务聊天的特殊性,在线状态在浏览网页期间改变的概率比较低,即使有改变浏览者在请求聊天时也能知道这种改变,对业务来说没有影响。
相对漂浮式弹出式能显示更多的内容,适合于做额外的宣传广告,广告内容可在后台编辑修改,此外还可显示浏览者访问网页的地点。
3 代码插入自动化
市场上有些类似的产品,插入引擎代码还是手工,客户注册账号后服务商把要插入的代码(含注册信息)交给客户,由客户手动把代码插入到网页中,当网页比较多时非常繁琐。通过后台管理网站的FTP服务器可进行自动插入,避免手工插入对网页的破坏。自动插入的流程图如下:
图2 代码插入流程
3.1 代码块插入和删除
针对不同的网页格式按从后查找的方式找出网页最后的标签[4],然后查找代码块的结束标签<!— END{www.szyhpx.com} —>和开始标签<!— BEGIN{www.szyhpx.com}—>,如果标签存在则要删除在网页的整个代码块,如代码块标志破坏则用日志形式记录网页名称。由于网页内容比较多,如搜索整个网页效率比较低,规定范围从网页结束签向前1.5/2倍的代码块大小。由于代码块中包含具体客户的个体信息,在通用代码块中设置了这些信息占位符,上传之前要替换占位符。插入删除规则说明如下:
1) WebPageYhJavScriptLoc 类中包含以上三个标签的在网页中位置,其值由下面方法求出。 WebPageYhJavScriptLoc insertYhCodeLoc=ComareArray. webPageFromLastFindArray(txtcont,begTag,endTag,webPageEndTag)。
2) 判断三个标签位置的合法性 insertYhCodeLoc.yhJavaScriptEndLoc>0 && insertYhCodeLoc.yhJavaScriptBegLoc==-1 为非法,抛出异常。
insertYhCodeLoc.yhJavaScriptEndLoc==-1 && insertYhCodeLoc.yhJavaScriptBegLoc〉0 合法但insertYhCodeLoc.yhJavaScriptEndLoc会转化成标签位置。
删除二标签位置之间的代码块。
3) insertYhCodeLoc.yhJavaScriptBegLoc==-1 && insertYhCodeLoc.yhJavaScriptEndLoc==-1在标签位置处直接插入代码。
3.2 网站的目录映射
把网站的目录结构映射到树形界面中,建立多层树形结构,客户根据树形目录选择要插入代码网页所在的目录,或者排除的不要修改的目录。代码中NamedVector 类中继承Vector系统类,包含父目录串,用于存放多个子目录。下面函数执行完成后,所有的目录按树形结构保存到第一次调用begVc对象中,代码范例如下。
public void createTreeModule( NamedVector begVc,String abPath) throws Exception
{
NamedVector subVc=null;
if(isIncludePath(abPath)) return;
// ftp获取本目录下的所有子目录
Vector
if(dirs==null || dirs.size()==0) return ;
for(int i=0;i { subVc=new NamedVector(dirs.get(i)); // 储存子目录 begVc.addSubVector(subVc); // 根目录特殊性 subVc.abPath=( abPath.equals("/") ? abPath+dirs.get(i):abPath+"/"+dirs.get(i) ); createTreeModule(subVc,subVc.abPath); }} 3.3 上传文件完整性的保证 在上传网页文件过程中,如果文件上传突然中断,将会导致网页内容的破坏,造成网页不能正常显示。网页文件下载到内存并插入代码完成后,在下载目录中建立类型和网页文件一致的临时备份文件,文件名称是系统生成的唯一的ID,在XML文件中登记这二个备份的文件,同时记录网页在FTP服务器中的目录。上传成功后删除所有这些信息,失败后要把备份文件重新上传(REDO/UNDO)。XML格式定义范例如下: 4 结束语 本文涉及实现的功能只是对传统聊天系统的扩展,即通过网页插件的形式把普通网页和聊天系统连接到一起,腾讯QQ就是一个实例,通过在网页中点击QQ聊天提醒进入浏览者桌面QQ聊天程序,双方都用QQ账号连接,这种方式缺陷是引起QQ号泄露,扩充其它管理功能受到限制。 把浏览者浏览网页过程和聊天产生数据管理起来并对之分析利用,这样一些原始数据收集也需要在网页中插入相关代码,并在后台建立业务数据管理,这些功能设计实现超出本文所讨论的范围。 参考文献: [1] Christophe Porteneuve. Javascript 修炼之道[M]. 巩朋, 张铁,译.北京:人民邮电出版社,2011:70. [2] Nicholas C Zakas.Javascript高级程序设计[M].北京:人民邮电出版社,2012:12. [3] Den Odell.Javascript RIA 开发实践[M].北京:清华大学出版社,2010:146. [4] Den Odell.Javascript RIA 开发实践[M].北京:清华大学出版社,2010:125.
2) 判断三个标签位置的合法性 insertYhCodeLoc.yhJavaScriptEndLoc>0 && insertYhCodeLoc.yhJavaScriptBegLoc==-1 为非法,抛出异常。
insertYhCodeLoc.yhJavaScriptEndLoc==-1 && insertYhCodeLoc.yhJavaScriptBegLoc〉0 合法但insertYhCodeLoc.yhJavaScriptEndLoc会转化成标签位置。
删除二标签位置之间的代码块。
3) insertYhCodeLoc.yhJavaScriptBegLoc==-1 && insertYhCodeLoc.yhJavaScriptEndLoc==-1在标签位置处直接插入代码。
3.2 网站的目录映射
把网站的目录结构映射到树形界面中,建立多层树形结构,客户根据树形目录选择要插入代码网页所在的目录,或者排除的不要修改的目录。代码中NamedVector 类中继承Vector系统类,包含父目录串,用于存放多个子目录。下面函数执行完成后,所有的目录按树形结构保存到第一次调用begVc对象中,代码范例如下。
public void createTreeModule( NamedVector begVc,String abPath) throws Exception
{
NamedVector subVc=null;
if(isIncludePath(abPath)) return;
// ftp获取本目录下的所有子目录
Vector
if(dirs==null || dirs.size()==0) return ;
for(int i=0;i { subVc=new NamedVector(dirs.get(i)); // 储存子目录 begVc.addSubVector(subVc); // 根目录特殊性 subVc.abPath=( abPath.equals("/") ? abPath+dirs.get(i):abPath+"/"+dirs.get(i) ); createTreeModule(subVc,subVc.abPath); }} 3.3 上传文件完整性的保证 在上传网页文件过程中,如果文件上传突然中断,将会导致网页内容的破坏,造成网页不能正常显示。网页文件下载到内存并插入代码完成后,在下载目录中建立类型和网页文件一致的临时备份文件,文件名称是系统生成的唯一的ID,在XML文件中登记这二个备份的文件,同时记录网页在FTP服务器中的目录。上传成功后删除所有这些信息,失败后要把备份文件重新上传(REDO/UNDO)。XML格式定义范例如下: 4 结束语 本文涉及实现的功能只是对传统聊天系统的扩展,即通过网页插件的形式把普通网页和聊天系统连接到一起,腾讯QQ就是一个实例,通过在网页中点击QQ聊天提醒进入浏览者桌面QQ聊天程序,双方都用QQ账号连接,这种方式缺陷是引起QQ号泄露,扩充其它管理功能受到限制。 把浏览者浏览网页过程和聊天产生数据管理起来并对之分析利用,这样一些原始数据收集也需要在网页中插入相关代码,并在后台建立业务数据管理,这些功能设计实现超出本文所讨论的范围。 参考文献: [1] Christophe Porteneuve. Javascript 修炼之道[M]. 巩朋, 张铁,译.北京:人民邮电出版社,2011:70. [2] Nicholas C Zakas.Javascript高级程序设计[M].北京:人民邮电出版社,2012:12. [3] Den Odell.Javascript RIA 开发实践[M].北京:清华大学出版社,2010:146. [4] Den Odell.Javascript RIA 开发实践[M].北京:清华大学出版社,2010:125.
2) 判断三个标签位置的合法性 insertYhCodeLoc.yhJavaScriptEndLoc>0 && insertYhCodeLoc.yhJavaScriptBegLoc==-1 为非法,抛出异常。
insertYhCodeLoc.yhJavaScriptEndLoc==-1 && insertYhCodeLoc.yhJavaScriptBegLoc〉0 合法但insertYhCodeLoc.yhJavaScriptEndLoc会转化成标签位置。
删除二标签位置之间的代码块。
3) insertYhCodeLoc.yhJavaScriptBegLoc==-1 && insertYhCodeLoc.yhJavaScriptEndLoc==-1在标签位置处直接插入代码。
3.2 网站的目录映射
把网站的目录结构映射到树形界面中,建立多层树形结构,客户根据树形目录选择要插入代码网页所在的目录,或者排除的不要修改的目录。代码中NamedVector 类中继承Vector系统类,包含父目录串,用于存放多个子目录。下面函数执行完成后,所有的目录按树形结构保存到第一次调用begVc对象中,代码范例如下。
public void createTreeModule( NamedVector begVc,String abPath) throws Exception
{
NamedVector subVc=null;
if(isIncludePath(abPath)) return;
// ftp获取本目录下的所有子目录
Vector
if(dirs==null || dirs.size()==0) return ;
for(int i=0;i { subVc=new NamedVector(dirs.get(i)); // 储存子目录 begVc.addSubVector(subVc); // 根目录特殊性 subVc.abPath=( abPath.equals("/") ? abPath+dirs.get(i):abPath+"/"+dirs.get(i) ); createTreeModule(subVc,subVc.abPath); }} 3.3 上传文件完整性的保证 在上传网页文件过程中,如果文件上传突然中断,将会导致网页内容的破坏,造成网页不能正常显示。网页文件下载到内存并插入代码完成后,在下载目录中建立类型和网页文件一致的临时备份文件,文件名称是系统生成的唯一的ID,在XML文件中登记这二个备份的文件,同时记录网页在FTP服务器中的目录。上传成功后删除所有这些信息,失败后要把备份文件重新上传(REDO/UNDO)。XML格式定义范例如下: 4 结束语 本文涉及实现的功能只是对传统聊天系统的扩展,即通过网页插件的形式把普通网页和聊天系统连接到一起,腾讯QQ就是一个实例,通过在网页中点击QQ聊天提醒进入浏览者桌面QQ聊天程序,双方都用QQ账号连接,这种方式缺陷是引起QQ号泄露,扩充其它管理功能受到限制。 把浏览者浏览网页过程和聊天产生数据管理起来并对之分析利用,这样一些原始数据收集也需要在网页中插入相关代码,并在后台建立业务数据管理,这些功能设计实现超出本文所讨论的范围。 参考文献: [1] Christophe Porteneuve. Javascript 修炼之道[M]. 巩朋, 张铁,译.北京:人民邮电出版社,2011:70. [2] Nicholas C Zakas.Javascript高级程序设计[M].北京:人民邮电出版社,2012:12. [3] Den Odell.Javascript RIA 开发实践[M].北京:清华大学出版社,2010:146. [4] Den Odell.Javascript RIA 开发实践[M].北京:清华大学出版社,2010:125.