ajax应用中,最常碰到的问题便是:你从某一个编码(如utf-8)的页面上,向另一不同编码(如gb2312)的页面传递中文参数,从而出现乱码问题,最要命的是,这两边,你都无法做任何改变。
一种简单有效的解决办法是在ajax发出请求的时候,用escape()函数将参数进行编码。它返回一个包含了 charstring 内容的字符串值( Unicode 格式)。所有空格、标点、重音符号以及其他非 ASCII 字符都用 %xx 编码代替,其中 xx 等于表示该字符的十六进制数。例如,空格返回的是 “%20″ 。字符值大于 255 的以 %uxxxx 格式存储。虽然有教程指出escape 方法不能够用来对统一资源标示码 (URI) 进行编码,而应该用encodeURI 和encodeURIComponent 方法来处理,但就我的使用情况来看,escape()方法有效得多。
另一种方法是引入一个第三方页面做中转,在该页面上进行编码处理。
(全文…)
Tags: Ajax, OPAC, utf-8, 乱码, 编码, 资源整合

3日,加入了VuFind Tech mail
list。个人认为,这是一个比较有前景的开源项目,代码规范,文档齐全,虽然VuFind在SourceForge还没什么人气,但在图书馆界却已经引起了极大的关注,并带动了数个项目的开源。尤为重要的是,他们的思路,和我的想法不谋而合——那就是不再依赖LIS,另谋出路,同时,他们选择的数据引擎SOLR,正是我想多加利用的开源程序之一。
5日,收到Andrew的回复,对于在美国之外有人关注VuFind,他们感到意外和惊喜——看来,他们对中国2.0的发展还不太了解,这需要国内同行多往国外期刊投文章,介绍偶们的实践才行。现在VuFind刚刚完成了翻译系统,已经向国际化迈出了实质性的一步。我加入VuFind Tech,可能会参与到文档翻译和中文版本的相关开发中。
最大的压力源于要做的事情太多,而我更希望能专心的投入做某件事情。Library2.0书稿一拖再拖,目前还有“自己开发一个tag系统”这一小节没完成,都已经不好意思跟万二和其他师友说抱歉了,只有这两天再努力一把,把初稿完成,再和大家一起完善,然后,把精力放到OPAC和网站的改造中去了。
好友现在已经是数据库部门的小主管,主持部门的工作,开始负责了人员招聘和培训,同时也坦言压力很大,担心人际关系过于复杂,担心被fire,呵呵,我说做好本职工作就是了。外面有外面的精彩,图书馆有图书馆的天地,大家都在为理想而努力。
Tags: OPAC, VuFind
友情敬告:开放是出路,服务是前途!
这两天本想继续写Ajax,回应一下
K师的博文和清心的提问,但下午碰到了件事情,之后偶不得不将之前所写的“Millennium系统OPAC整合”系列文章做出一些改动——主要是将一些被某些人视之为神圣的东西,应要求供奉起来。
但说实话,神圣么,偶不觉得,不过《国产007》的司令说了:即使是一张厕纸,也要好好对待的。因此,偶应要求去掉或改写了相关内容:如相关屏幕截图(即使是偶们馆的哦)、相关参数内容及其他。如果有朋友需要进一步交流,请先联系他们,取得授权,否则偶们只能偷偷摸摸的哦~特此公告,嘿嘿~
在
整合之三:构建自己的WebBridge一文中,原本思路是采用系统开放的参数,来提交到第三方服务器,从而实现相关功能。那么,如果系统没有这些参数,或者说偶觉得这些参数过于恶心,不用,还能不能实现我们想要的功能呢?
能!
这就是Ajax。
Ajax伟大的地方 在于其所带来的Web
应用客户端化,在于其提供的异步交互颠覆了传统的“提交/等待/
重新显示” 模式。
那么对于整合之三一文,偶在这里提出一个更好的解决方案,该方案,具有更广泛的应用价值,也就是说,本方案已经不再局限于Mllnnm系统了。
第一节:得到参数
让我们回头看看整合之三一文中所隐藏掉的东西,那是告诉我们如何获取参数的一段话。我们在那里,绕来绕去得到了一个检索词,和一个ISBN号,从而实现参数的提交。
现在我觉得这种方式很笨,我决定,通过Ajax来取得我想要的东西——最正规的方式是通过Javascript脚本将当前用户浏览器的DOM文档分解,使用getElementsByTagName()逐一分析并得出任意页面上的值。
当然,也有些捷径。
一般来说,大部分OPAC系统的参数提交,都是通过GET方式进行——我们可以通过看看浏览器的地址栏上是否带有一串很长的参数得出判断。这一串地址,我们要得到它,可以通过window.location.href、window.location.search等等方式获取。获取这串URL之后,我们可以发现,该URL里面包含了许多丰富的信息,我们所需要做的只是进行简单的文本分析。
比如,通过关键词检索得出《thinking in java》一书的书目详细信息页面Url是:
(该URL不需授权吧?有点怕怕呢……)
将多余的信息去掉,我们可以得出:
SUBKEY=thinking%20in%20java
这其实就是用户提交的关键字。
除了URL,我们还可以用FORM,像在Millennium系统的书目信息页面,仍然提供了检索框,方便用户进行进一步检索,对于该检索框的值,我们可以通过document.form.searcharg.value语句来获取,当然,这是不正规的写法,正规写法是:doucument.getElementsByTagName(”searcharg”).getAttribute(”value”)。
如果说URL和FORM中没有我们想要的值,如本例子中的ISBN号,那么我们只有老老实实的分析DOM,并找出
ISNB号所在的单元格,再通过innerHTML()属性获取相关值。
而上面这一切,都只是通过一段脚本,在用户浏览器上执行的。
那么得到了参数之后,接下来就要和服务器通讯了。
第二节:异步通讯
用户在继续他的操作,而浏览器已经在不打扰用户的情况下,跟我们的服务器通讯了。
这就是XMLHttpRequest对象。
XMLHttpRequest对象可以通过脚本创建,并且可以给服务器发送HTTP请求,当然,毫无疑问的它能接收服务器的反馈。我们通过以下语句创建一个XMLHttpRequest对象:
xRequest=new
XMLHttpRequest();//创建对象,实际上要复杂一些
同时,我们通过onreadystatechange定义它的回调函数,然后将相关参数传送至服务器。
xRequest.onreadystatechange=onReadyState;//定义回调函数
xRequest.open(HttpMethod,url,true);//打开http访问
xReqeust.send(params);//传送相关参数
而在在服务器端,我们接收用户提交的参数,并执行数据库操作,完成后,将相关信息反馈回客户端浏览器。反馈数据的形式可以是txt、html、甚至是JavaScript数组等。
第三节:更新页面的某一部分
客户端浏览器通过侦听回调函数,确定服务器处理完请求后,就可以通过createElement()等方法来实现文档的修改,把相关反馈信息,更新到当前文档即可。代码…..略……
以上三节内容,已经给我们揭示了一个很好的方向,对于一些封闭的WEB应用,我们可以通过Ajax,实现很多原本不可实现的事情。大家一起发挥想象吧~
总结:
呵呵,写着写着,就变成写Ajax了,其实Ajax是非常有用的工具,随着用户“我的地盘我做主”的吼声越来越多,相关技术肯定会不断涌现。保守,只能被淘汰。软件不是什么值钱的东西,服务才是。
Tags: Ajax, millennium, OPAC, 开放
因为无知,所以进步,只有努力,才能专业——以此自勉。
对于近乎封闭的OPAC系统来说,AJAX是把利剑。为什么这么说呢?
OPAC系统失败之处:
1、绝大部分基于自有web解析服务器,web页面程序不开放,无法进行数据层面的操作和修改;
2、绝大部分基于封闭的数据库,用户无法直接访问数据库取到相关记录;
3、几乎没有支持用户开发需求的第三方接口。
AJAX的锋利之处:
1、运行在客户端浏览器上,与OPAC平台无关。只要能在OPAC页面中嵌入相关脚本,即可实现相关功能;
2、可以通过DOM操作,获取用户当前页面上的所有信息——包括书名、ISBN号、索书号等等;
3、可以在不影响用户操作的前提下,通过xmlhttprequest对象,向某一服务器发送请求,并得到反馈数据;
4、可以通过DOM操作,无刷新改变当前页面的结构与内容。
由上面的对比,可以看到,要做OPAC资源整合,AJAX是绝妙的武器。那么操作AJAX的基础是不是很简单呢?
是的,下面是一些最基本的操作方式,但这些基本的操作方式,已经足以让我们完成80%的工作。
首先,假设有这么一个理想的页面:
sample.html
<html>
<head>
<title>Ajax in
action</title>
</head>
<body>
<table width=”200″
border=”1″>
<tr>
<td>书名:</td>
<!–此处定义了td标签的id–>
<td
id=”t”>Ajax in Action</td>
</tr>
</table>
</body>
</html> |
那么我们要嵌入脚本,是很容易的事情,我们可以把脚本直接写到里面,也可以通过外接脚本文件的形式嵌入,例如,在</head>标签之上加上一行:
<script
type=”text/javascript”
src=”ajax_sample.js”></script>
二、页面信息的读取:
脚本是AJAX的核心,只有通过脚本,才能实现AJAX的操作。
我们现在要实现ajax_sample.js对sample.html页面信息的读取,确切的说,是要得到该页面上的书名。
ajax_sample.js:
window.onload=function() //当网页加载后运行脚本
{
//通过id获取当前文档的书名单元格对象
var
objTitle=document.getElementById(’t');
//输出对象内容
alert(objTitle.innerHTML);
} |
通过document.getElementById()方法,我们分别获取了sample.html网页中的书名单元格对象,并通过innerHTML属性得到了具体的值——“Ajax
in
Action”——这样,我们初步实现了文档内容的分析操作。
当然,sample.html具有一定的理想性——结构清晰、具有id属性——目前OPAC系统里面,我相信大部分页面的HTML是极其恶心、惨不忍睹的,但是这并不能阻挡AJAX的步伐,除了getElementById()方法,我们还可以通过getElementsByTagName()来实现节点的搜索。
三、发送请求到服务器:
好了,我们顺利的分析了文档的内容,那么在这里首先问大家一下:分析用户文档的意义何在?
意义在于,我们要知道读者正在浏览的信息,比如是哪一本书,这样我们才能针对读者的行为给他们更多的惊喜。
在本例中,得到了书名之后,我们就可以通过xmlhttprequest对象,将书名传送到专门的服务器,由服务器去实现更多的功能。
ajax_sample.js:
window.onload=function() //当网页加载后运行脚本
{
//通过id获取当前文档的书名单元格对象
var
objTitle=document.getElementById(’t');
//输出对象内容
//alert(objTitle.innerHTML);
//与服务器通讯
sendRequest(”[服务器处理程序的URL]“,”t=”+objTitle.innerHTML);
}
function
CreateXmlHttpRequest()//创建XmlHttpRequest对象
{
var xRequest=null;//定义
if(window.XMLHttpReqeust)//支持XMLHttpReqeust对象
{
xRequest=new XMLHttpRequest();
}
else if(typeof ActiveXobject !=”undefined”)//支持ActiveX对象
{
xRequest=new
ActiveXobject(”Microsoft.XMLHTTP”);
}
return xRequest;//返回
}
function
sendRequest(url,params)//发送请求函数
{
HttpMethod=”GET”;//传送方式
var
sRequest=CreateXmlHttpRequest();//创建实例
if(sRequest)
{
sRequest.open(HttpMethod,url,true);//打开http访问
sReqeust.send(params);//传送相关参数
}
} |
四、服务器的反馈程序:
通过上面的步骤,已经实现了客户端将数据传送到服务器,这时,服务器可以做的事情很多了,比如,检索一下有没有电子图书,并向用户返回相关信息。
ajaxsample.java
|
//yuanxinz.2007.05.09
package ajaxsample;
import java.io.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.servlet.*;
import java.servlet.http.*;
public class ajaxsample extends
HttpServlet
{
public void init(ServletConfig config) throws
ServletException
{
//…..
}
protected void doGet(HttpServletRequest
request,HttpServletResponse response) throws
ServletException,IOException
{
String s =
request.getParameter(”s”);//获取参数
//执行电子图书数据库检索
……
rs = pool.getRs(”select * from
表 where 题名 like ‘%”+s+”%’);
try{
if(rs.next())
{
rs.previous();
//将结果输出为文本
PrintWriter
out = response.getWriter();
response.setContentType(”text/plain;charset=gb2312″);
response.setHeader(”Cache-Control”,
“no-cache”);
response.setHeader(”Pragma”,
“no-cache”);
String
outstr=”";
int
i = 0;
while(rs.next())
{
outstr
= outstr + rs.getString(”题名”) + “|” + rs.getString(”url”) +
“\n”;
i++;
}
out.println(outstr);
out.close();
}
else
{
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
}
//关闭数据库连接之类的….
…….
}
catch(SQLException e)
{
e.printStackTrace();
}
}
} |
上面的servlet在接到用户请求后,将进行相关检索,并返回一个文本:
Ajax in Action|http://******
……
Ajax in action
**|http://*****
AJAX可以返回多种类型的数据,包括html、XML文档和javascript脚本等等。
五、接收反馈数据,并修改当前文档:
现在一切又回到了用户浏览器,首先,我们要通过定义回调处理函数,来确定服务器已经将相关的数据返回。
ajax_sample.js:
window.onload=function() //当网页加载后运行脚本
{
//通过id获取当前文档的书名单元格对象
var
objTitle=document.getElementById(’t');
//输出对象内容
//alert(objTitle.innerHTML);
//与服务器通讯
sendRequest(”[服务器处理程序的URL]“,”t=”+objTitle.innerHTML);
}
function
CreateXmlHttpRequest()//创建XmlHttpRequest对象
{
var
xRequest=null;//定义
if(window.XMLHttpReqeust)//支持XMLHttpReqeust对象
{
xRequest=new XMLHttpRequest();
}
else if(typeof
ActiveXobject !=”undefined”)//支持ActiveX对象
{
xRequest=new
ActiveXobject(”Microsoft.XMLHTTP”);
}
return
xRequest;//返回
}
function
sendRequest(url,params)//发送请求函数
{
HttpMethod=”POST”;//传送方式
var
sRequest=CreateXmlHttpRequest();//创建实例
if(sRequest)
{
//这里调用回调
sRequest.onreadystatechange=onReadyState;
sRequest.open(HttpMethod,url,true);//打开http访问
sReqeust.send(params);//传送相关参数
}
}
function
onReadyState()
{
var redy=sRequest.readyState;//获取sRequest实例的状态
var data=null;
if(ready=4)//完成状态
{
data=xRequest.responseText;
}
else
{
data=”正在读取相关数据….”
}
} |
用户浏览器收到服务器反馈的文本后,就可以通过createElement()等方法来实现文档的修改。
ajax_sample.js:
window.onload=function() //当网页加载后运行脚本
{
//通过id获取当前文档的书名单元格对象
var
objTitle=document.getElementById(’t');
//输出对象内容
//alert(objTitle.innerHTML);
//与服务器通讯
var
empty=document.getElementById(’empty’);//定义一个空节点
sendRequest(”[服务器处理程序的URL]“,”t=”+objTitle.innerHTML);
}
function
CreateXmlHttpRequest()//创建XmlHttpRequest对象
{
var
xRequest=null;//定义
if(window.XMLHttpReqeust)//支持XMLHttpReqeust对象
{
xRequest=new XMLHttpRequest();
}
else if(typeof
ActiveXobject !=”undefined”)//支持ActiveX对象
{
xRequest=new
ActiveXobject(”Microsoft.XMLHTTP”);
}
return
xRequest;//返回
}
function
sendRequest(url,params)//发送请求函数
{ |
Tags: Ajax, millennium, OPAC
Millennium系统的OPAC中,有一个产品叫WebBridge,通过它,读者可以在查阅相关书目信息的同时,以OPENURL的方式在各类开放数据库中获取相关全文、电子图书、搜索引擎结果及其他相关信息。如下图所示(点击放大):
(应要求,不得放截图,大家要看自己找去~嘿嘿,若被授权,可email偶)
不可否认,WebBridge是个好东西,但是好东西往往意味着高价钱,(应要求,此处省略若干字…..若被授权,请EMAIL偶)。有句俗话叫癞蛤蟆想吃天鹅肉,小钟就像那见过了天鹅,却只能流着口水的癞蛤蟆,始终惦记在心里啊~
所谓庸人自扰,相思成病,看着好东西却得不到是很伤的,所以小钟无奈之下退而求其次——天鹅肉吃不到,但鸭子咱会养,咱整个鸭子试试!
言归正传,分析一下这个WebBridge,关键在于其针对读者的检索结果,在结果页面上提供了一个或若干个相关参数,通过这些参数,可以构建出相应的URL,从而提交到各类开放数据库。
就这么个简单的东西。
那么小钟要做的事情就两点:
一、找出一个有用的参数。这个参数可以是检索词,题名或者ISBN号等等。
二、找出一个可以修改检索结果页面的地方,让检索结果页面可以显示部分自定义的内容。
而这两点其实都不难。
一、(应要求,在此省略字数400多字,若被授权并需进一步交流,请email小钟)
二、对页面进行修改,这就更简单了,只要能输入HTML的地方,就可以任意嵌入我们想要嵌入的东西,方法有很多,比如,嵌入一个IFRAME、嵌入一个DIV、嵌入一段脚本……
具体实现过程如下:
一、(应要求,此处省略300多字,若被授权并需进一步交流,请email小钟)
二、提供一个webbridge.asp网页,该网页用于接收参数并实现相关功能,例如:
|
dim para ‘参数
para=trim(request(”para”))
if IsNumeric(replace(para,”x”,”"))=true then
‘如果传入的是ISBN号
response.Write(”随书光盘:“)
‘查找随书光盘信息
….
if
…. then
如有光盘可请求上网
else
下载光盘
end
if
….
response.Write(”电子图书:“)
‘查找电子图书
超星数字图书
方正电子图书
书生电子图书
NetLibrary
GOOGLE查找电子图书
response.Write(”电子期刊:“) ‘查找期刊
….
else ‘如果传入的是检索词
….
end if
|
效果如下图(点击放大):
(应要求,不得随便截图,自己看去,若被授权,可EMAIL偶)
读者点击下载光盘,可以下载《Thinking in
java》这本书的随书光盘,点击GOOGLE查找免费电子图书,可以提交检索到GOOGLE图书等等。
当然,由于能用的参数有限,也没有用到AJAX,目前大概也只能做到这个程度,聊胜于无吧。
其实,对于所需的各类参数,即使Millennium的OPAC系统一个参数都不提供,我们也完全可以使用javascript
+
Dom,进行用户页面分析获得,进而通过AJAX,与各类数据库进行无刷新操作!
而这就是小钟下一步要去做的事情:
一个基于JAVA+AJAX的,独立的、开源的书目TAGGING系统,敬请期待。
一点补充:在上面的webbridge.asp文件中,仅仅通过判断传入的参数是否为数字而确定是不是ISBN号存在一些bug,建议根据来源页面判断传入的参数是检索词还是ISBN号。在ASP中,判断来源页面的环境变量为HTTP_REFERER。
Tags: Ajax, millennium, OPAC, webbridge