西西河

主题:【原创】AJAX在西西河的一个应用简析 -- 铁手

共:💬16 🌺7 新:
全看树展主题 · 分页 下页
家园 【原创】AJAX在西西河的一个应用简析

Asynchronous JavaScript and XML ==> AJAX

关于AJAX的历史和一些应用以及实现机理,可以在GOOGLE里很容易的查找到,这里就不多说。只是简单的说明一下它目前在西西河的第一个应用,以及在使用过程中所碰到的问题,并请熟悉的朋友讨论指点一下。

AJAX的机理,说起来很简单,就是在 JAVACRIPT 中直接和服务器取得联系,把相关内容拿回到客户端,然后把零件一个个拆下来,再分别放到当前页面中合适的地方去。

最核心的部分,就是在JAVASCRIPT中实现静悄悄获取页面内容的的功能模块。

这个功能,在非IE的浏览器中很容易实现,因为这些浏览器里都内置这个模块。用以下的语句,可以得到这个功能模块。

if (window.XMLHttpRequest) {

zHTTP_Req = new XMLHttpRequest();

if (zHTTP_Req.overrideMimeType) {

zHTTP_Req.overrideMimeType("text/xml");

}

}

如果是IE浏览器,则需要ActiveXObject的支持,可以用以下语句得到

if (window.ActiveXObject){

try{

zHTTP_Req = new ActiveXObject("Microsoft.XMLHTTP");

}catch(e){

try{

zHTTP_Req = new ActiveXObject("Msxml2.XMLHTTP");

} catch (e) {}

}

}

在得到这个打开后门偷偷交流的功能模块后(在这里是 zHTTP_Req),需要做的事情就是告诉这个模块在什么情况下做什么事情。这个是通过事件驱动来实现,具体的说,就是给这个模块的 onreadystatechange 事件定义一个函数。

function IfYouClickMeIWillKickYouBack{ // 用来对某个BUTTON点击做反应的函数

zHTTP_Req.onreadystatechange = function(){

if (zHTTP_Req.readyState == 4) {

if (zHTTP_Req.status == 200) {

var zlTmpV = zHTTP_Req.responseXML.getElementsByTagName("UPInfo")[0].childNodes[0].nodeValue; //XML的格式

。。。

。。

//zlDobj.innerHTML = zHTTP_Req.responseText; //文本方式得到内容

}

}

}

zHTTP_Req.open("GET", url, true); //我要看到某个页面的内容。

zHTTP_Req.send(null);

}

上面这段里,在提出要得到某个页面的内容的请求后,这个功能模块不断检测请求是否得到响应,内容是否正常返回。

正常返回后,可以有两种方式来得到所请求的内容。如果是简单的文本,可以用 zHTTP_Req.responseText ,如果是XML格式的,则需要相应的处理,来得到分类的内容。

西西河目前的一个简单AJAX应用,是实现在论坛首页最下面的【发贴信息】这个链接里。FIREFOX,SAFARI里面都没有任何问题,但是在IE里面,有时候可以有时候不可以,邪门的很。

还有一个问题,我原本是想用简单的文本方式,也就是在所请求的URL里,把内容都格式好以后(包括HTML 标签符号)输出,希望能够使用 responseText 来直接放到页面某个位置,结果所有中文都成为????的形式,而英文、数字等则没有显示问题。

后来不得以,只能使用 responseXML 来实现。只是,对XML也不是很熟悉。河里的XML FEED,也是用了尽可能简单的方式。

如果有人能够解决 responseText 中文内容乱码的问题的话,事情就会简单很多,西西河里很多地方也可以应用一下。

关键词(Tags): #ajax#乱码#xml元宝推荐:Highway,
家园 IE里面其实没什么特别的地方,我看过不少微软的例子。

比如这一个

外链出处

微软对AJAX的支持将是全方位的,从Server到Client端。现在他们搞了一个Project,叫做Atlas,就是要全面进军AJAX,并且要让Programmer近量不手写JavaScript。

家园 不手写代码很重要。最近也就是琢磨一下,也不知道是真好还是假好

另外,最近看到FLASH里面也有类似的功能,这么一想,缺点大家一样,都是对搜索引擎不友好,甚至AJAX还要冒用户关闭JAVASCRIT的风险,好处上面,FLASH的画面显然要好一些,还真不知道以后到底是谁的天下:)

家园 charset?

还有一个问题,我原本是想用简单的文本方式,也就是在所请求的URL里,把内容都格式好以后(包括HTML 标签符号)输出,希望能够使用 responseText 来直接放到页面某个位置,结果所有中文都成为????的形式,而英文、数字等则没有显示问题。

输出这个片段response的时候,有没有设charset=gb2132?

家园 因为是想直接输出需要的内容,所以是没有头部字符集的设定

不过,也许可以尝试一下使用一下输出一个完整页面,包括字符集信息,然后在JAVASCRIPT中再做分离提取。

不过,如果那么做的话,似乎和用XML就没有多少区别了。

家园 不是HTML里的head

老兄有没有试试写response的时候直接设HTTP header里的ContentType? 手边没有.NET的API文档,大概是:

response.CharSet="GB2312";

家园 这个不清楚

AJAX没做过,不知道啊。不过servlet在response输出日语的时候是需要指定编码shift-jis的,我估计这个也需要指定一下。毕竟这些东西都是西方人搞得,默认的方式应该不支持双字节。

家园 好像不是这个问题

我用的是PHP。又试了一下。我用一个HTML的静态文件为源,也同样是乱码。不过如果这个文件是UTF-8的格式保存的话,则可以正常显示。

看来这个源需要是UTF-8的编码方式。

看来有必要不管死活也要转到UNICODE上了????GB18030怎么办?

家园 有没有试过把送回的字符串用UTF-8或UTF-16编码?
家园 这个问题解决了吗?

我弄过一点AJAX,希望能帮个小忙。

家园 乱猜一下原因

乱猜一下原因,有几个地方都会用到ENCODING。

硬盘上的文件有它自己的ENCODING,比如在XP上,用NOTEPAD,你可以把一个文件用ANSI,UTF-8,UNICODE等方式存取,如果打开的ENCODING与存放的ENCODING不一致,会有乱码。

另外,服务器与客户端的转输内容,也会。对于XML,UTF-8是DEFAULT的,如果你的文件ENCODING不是UTF-8,应当转成UTF-8。否则也会有乱码。如用HTML,可以检查一下DEFAULT ENCODING,如果不一致,你有可能也需要转一下码。

当然,还有一个地方就是客户端的BROWSER,不过不太可能。

家园 不好意思,回复有些晚。很希望能够得到帮助。具体问题是这样

如果原文件是UTF-8的,直接用TEXT没有问题。

不过那样的话,我想可能还是直接用XML格式比较好一些,因为在XML里可以设定语言,也不占太多空间。

用XML的问题是如果要用格式化的HTML段落,需要用对格式码编码,会增加一些流量。呵呵,这方面我很小心,传送数据越少越好。

我现在有两个问题:

一个是XML的元素怎么在用JAVASCRIPT获取。我用的比较简单,就是

zHTTP_Req.responseXML.getElementsByTagName("UPInfo")[0].childNodes[0].nodeValue;

这样的方式,但是如果是有多个NODE呢?这方面暂时没时间去学。如果你能够另开一个主题专门谈这个的话,实在是很感谢了。

还有一个问题,就是我现在这个应用中,在IE里老是出现OBJECT NOT FOUND的错。出错点就在上面列举的那段获得NODE值的代码里,不知道错在什么地方。

家园 试着答一下

如果原文件是UTF-8的,直接用TEXT没有问题。

不过那样的话,我想可能还是直接用XML格式比较好一些,因为在XML里可以设定语言,也不占太多空间。

事实上,XML文件内容的ENCODING和XML文件里设置可以是不一样的。比如,你可以把在XML PROLOG里将ENCODING设成是ISO-8859-1,但是如果将这个文件本身用UTF-8方式存到硬盘上,就会造成不一致,可能会出现乱码,当然如果文件本身存成UTF-8格式,就没有问题了。

另外在上一帖里,我忘了谈WEB SERVER或其PLUGIN本身ENCODING问题,因为我用的是J2EE平台,而JAVA内部的ENCODING总是UNICODE。JAVA在读外部文件时,如果不指定特别的ENCODING参数,总是用所在的计算机DEFAULT ENCODING,然后将其转为UNICODE的,写的时候反过来,会将UNICODE转成所在的计算机DEFAULT ENCODING。

我现在有两个问题:

一个是XML的元素怎么在用JAVASCRIPT获取。我用的比较简单,就是

zHTTP_Req.responseXML.getElementsByTagName("UPInfo")[0].childNodes[0].nodeValue;

这样的方式,但是如果是有多个NODE呢?这方面暂时没时间去学。如果你能够另开一个主题专门谈这个的话,实在是很感谢了。

另开主题,我都不知道该说些什么,又从何而谈。针对你的问题说两句,如果你的XML比较复杂,建议直接用HTML;如果你的XML比较简单,比如,在ROOT下只有一个层,如这个例子

<?XML .... ?>

<myxmlroot>

<xyz> ... </xyz>

<123>... </123>

....

</myxmlroot>

[/QUTOE]

也就是说,XYZ和123这样的NODE里再不包含SUBNODE,就可以这样干

[QUOTE]var root, i, oNodeList, item;

root = xmlDoc.documentElement;

oNodeList = root.childNodes;

for (i=0; i<oNodeList.length; i++)

{

Item = oNodeList.item(i);

// ....

}

如果你可以给我URL,我可以给你写一个简单的框架。如果是HTML的,我可以帮你试

一下错误在什么地方。

家园 试一下:

用AJAX来GET回一个页面时,RESPONSETEXT里面的中文多半会出现乱码,这是因为xmlhttp在处理返回的responseText的时候,是把resposeBody按UTF-8编码进解码考形成的,如果服务器送出的确实是UTF-8的数据流的时候汉字会正确显示,而送出了GBK编码流的时候就乱了。解决的办法就是在送出的流里面加一个HEADER,指明送出的是什么编码流,这样XMLHTTP就不会乱搞了。

PHP:header('Content-Type:text/html;charset=GB2312');

ASP:Response.Charset("GB2312")

JSP:response.setHeader("Charset","GB2312");

家园 抑或是:

XMLHTTP得到Response时假定Response是UTF8编码的,如果Response是 XML,那还可以通过encoding来指定编码,但HTML就不行了。(见鬼的GB2312,再次打倒!)所以它把含GB2312编码的HTML当成 UTF8格式,不出错才有鬼!

不过好在还有补救的办法:XMLHTTP的responseBody 属性里包含的可是未解码的Resonse——"a raw undecoded bytes as received directly from the server" :),唯一的问题是,responseBody返回的是一个unsigned bytes数组,我们怎么去访问它,怎么把它转换成BSTR?

这就是为什么我在上面把代码改成VBScript的原因——VBScript Can do it,but javascript Cannot!

代码见下:

<SCRIPT language="VBScript">

Function URLEncoding(vstrIn)

strReturn = ""

For i = 1 To Len(vstrIn)

ThisChr = Mid(vStrIn,i,1)

If Abs(Asc(ThisChr)) < &HFF Then

strReturn = strReturn & ThisChr

Else

innerCode = Asc(ThisChr)

If innerCode < 0 Then

innerCode = innerCode + &H10000

End If

Hight8 = (innerCode And &HFF00)\ &HFF

Low8 = innerCode And &HFF

strReturn = strReturn & "%" & Hex(Hight8) & "%" & Hex(Low8)

End If

Next

URLEncoding = strReturn

End Function

Function bytes2BSTR(vIn)

strReturn = ""

For i = 1 To LenB(vIn)

ThisCharCode = AscB(MidB(vIn,i,1))

If ThisCharCode < &H80 Then

strReturn = strReturn & Chr(ThisCharCode)

Else

NextCharCode = AscB(MidB(vIn,i+1,1))

strReturn = strReturn & Chr(CLng(ThisCharCode) * &H100 + CInt(NextCharCode))

i = i + 1

End If

Next

bytes2BSTR = strReturn

End Function

strA = URLEncoding("submit1=Submit&text1=中文")

oReq = CreateObject("MSXML2.XMLHTTP")

oReq.open "POST","http://ServerName/VDir/TstResult.asp",false

oReq.setRequestHeader "Content-Length",Len(strA)

oReq.setRequestHeader "CONTENT-TYPE","application/x-www-form-urlencoded"

oReq.send strA

alert bytes2BSTR(oReq.responseBody)

</ScRIPT>

用这个再试试看?

全看树展主题 · 分页 下页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河