Dedian  
-- 关注搜索引擎的开发
日历
<2006年10月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234
统计
  • 随笔 - 82
  • 文章 - 2
  • 评论 - 228
  • 引用 - 0

导航

常用链接

留言簿(8)

随笔分类(45)

随笔档案(82)

文章档案(2)

Java Spaces

搜索

  •  

积分与排名

  • 积分 - 64117
  • 排名 - 816

最新评论

阅读排行榜

评论排行榜

 

---祝大家中秋愉快---

Ajax (AsynchronousJavaScript and XML)是近年来流行的一门web 技术。在Blogjava上看到有人开始在介绍AJAX,但仿佛流于概念或理论的东西,对于想用Ajax的初学者似乎不是很make sense。我想,学习任何一样新的技术,例子和步骤是极为make sense的两样东西。

笔者想结合过去的学习经验简单讲讲使用Ajax的基本步骤和举几个实用例子。由于笔者主要在于后台端的开发,所以很多脚本并不是很擅长。Ajax也主要限于以前大学的修课和近期的一些为后台端程序的测试的简单实现。所以只是一个抛砖引玉的使用Ajax版本,欢迎相互学习交流。

0. 导读

    1。使用Ajax的基本流程
   
2。使用Ajax的基本步骤。(简单例子--> Demo)
    3。
再来一个例子(Google Suggest)。(Demo)
    4。家庭作业 :)


1。使用Ajax的基本流程

在笔者看来,Ajax更像是一个简单的网络框架,它描述着如何高效地使网络前端的数据展现和网络后端的数据之间的交互。基本上,就是浏览器提供一个XMLHttpRequest(当然在IE里是ActiveXObject)的对象向后台端的脚本程序或者Servlet Classes发送http请求,从后台端的回应中获取文本数据(如xml格式和最近有人讨论的Json格式)并嵌入前台段的网页中或脚本中。

下图是一个简单的流程图:



2。使用Ajax的基本步骤。

下面,我们结合上面的流程,以及一个简单的例子(见这篇文章)过一遍基本的步骤。(蓝色代码为标准写法)

第一步:Form 代码:接受前台端的输入,并通过Action方法(方法函数里包含创建XMLHttpRequest对象)把request post到后台端。

<input id="username" name="username" type="text"
  onblur="checkName(this.value,'')" />
<span class="hidden" id="nameCheckFailed">
  This name is in use, please try another.
</span>

<script language="javascript">
function checkName(input, response)
{
  if (response != ''){
    // Response mode
    message   = document.getElementById('nameCheckFailed');
    if (response == '1'){
      message.className = 'error';
    }else{
      message.className = 'hidden';
    }
  }else{
    // Input mode
    url  = 'http://localhost/xml/checkUserName.php?q=' + input;
    loadXMLDoc(url);
  }
}

var req;

function loadXMLDoc(url)
{
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        req.onreadystatechange = processReqChange;
        req.open("GET", url, true);
        req.send(null);
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = processReqChange;
            req.open("GET", url, true);
            req.send();
        }
    }
}
</script>


注:
1。 这里的form只是一个input box,action的方法是onblur,就是响应失去焦点的事件,然后调用一个函数checkName, 这个函数里通过XMLHttpRequest向PHP server script 发送Post请求(看得出来,这里的php server script的文件名叫checkUserName.php,唯一参数是q)。
2。函数loadXMLDoc里有个通用的创建XMLHttpRequest对象的代码,标准代码整理如下:
        var req;
        function foo()
        {
            req = false;

            // branch for native XMLHttpRequest object
            if(window.XMLHttpRequest)
            {
                try
                {
                    req = new XMLHttpRequest();
                }
                catch(e)
                {
                    req = false;
                }
            }
            else if(window.ActiveXObject) // branch for IE/Windows ActiveX version
            {
                try
                {
                    req = new ActiveXObject("Msxml2.XMLHTTP");
                }
                catch(e)
                {
                    try
                    {
                        req = new ActiveXObject("Microsoft.XMLHTTP");
                    }
                    catch(e)
                    {
                        req = false;
                    }
                }
            }
            if(req)
            {
                  
//do something here
             }
           

        }

第二步:响应文本处理代码:XMLHttpRequest对象里有个类似消息响应函数的属性,即通过设置 req.onreadystatechange 来告诉XMLHttpRequest在哪个函数里处理服务端返回的文本信息。
如在上面的例子中:
req.onreadystatechange = processReqChange;
那么我们接着要有一个processReqChange的函数:
function processReqChange() 
{
// only if req shows "complete"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200)
{
// ...processing statements go here...
processResponse();
} else {
alert("There was a problem retrieving
the XML data:\n" + req.statusText);
}
}
}


function processResponse()
{
response = req.responseXML.documentElement;
method = response.getElementsByTagName('method')[0].firstChild.data;
result = response.getElementsByTagName('result')[0].firstChild.data;
eval(method + '(\'\', result)');

}
注:
1。 基本上processReqChange 函数是标准代码的写法。
2。这里要用到前面定义的全局变量(XMLHttpRequest对象)req

第三步:后台端代码(这个例子是php server script):接受前台端的请求,处理其参数,并返回相应的结果。

文件名: checkUserName.php

<?php
header('Content-Type: text/xml');

function nameInUse($q)

  if (isset($q)){
    switch(strtolower($q))
    {
      case  'drew' :
          return '1';
          break;
      case  'fred' :
          return '1';
          break;
      default:
          return '0';
    }
  }else{
    return '0';
  }
 
}
?>
<?php echo '<?xml version="1.0" encoding="UTF-8"  standalone="yes"?>'; ?>
<response>
  <method>checkName</method>
  <result><?php
    echo nameInUse($_GET['q']) ?>
  </result>
</response>
注:代码很简单,就不用解释了。这里返回的是xml格式的字符串。

总体效果见这里
输入"fred"或者"drew"的名字,失去焦点后会显示名字已存在的信息。


 3。再来一个例子。

这里再讲一个实用的例子,这是以前上课的一个课堂作业,也很有代表性。是关于Google Suggest(好像新的Google Toolbar上就用的这个功能)的应用问题。这里是写好的DEMO。现在越来越多的网站提供类似Web Service的API, 我们利用他们提供的API URL可以返回一些我们用的着的数据,放在我们的网页上。这里就用的上Ajax。只不过有些返回来的文本数据是xml格式的,就可以利用上面的简单例子来处理,但很多像Google Suggest那样是返回一段类似代码格式的文本。我们就要利用Javascript的eval函数,把这些文本当作一段代码在嵌入自己的网页中。如果嵌入的代码中含有函数,则需要自己再写一个同名的函数作为实现。(这就是流程图中的optional的func 3)

这里完整代码就不贴了,贴一些关键代码(原本后台端是用Java Servlet写的,但做demo的空间没有Tomcat不支持Servlet,所以改用Php实现,大家可以自己用Java再写一边作为家庭作业 :) ):

1) form 代码:

<form name = "QForm" method="POST" action="google_suggest.php">
    <table bgcolor="8080C0" width="90%" >
    <tr>
        <td  nowrap>Search Term:</td>
        <td ><input type="text" name="qtext"  onkeyup="return GetSuggestion()" size="60"></td>
    </tr>
    <tr>
        <th colspan="2" align="left" bgcolor="#A8A8FF"><DIV id=google_suggest_target>results go here . . . </DIV></th>
    </tr>
    </table>
    </form>

注:
a. 看得出来,要把查询的字符串post到google_suggest.php上
b. action的函数是GetSuggestion(),其返回的字符串会显示在预留的网页空间里。

2) 后台端代码(PHP):这里主要接收前台的请求,并不请求转化为向Google Suggest的API URL请求,把接收到的文本信息返回给前端。代码很简单,如下:

文件名:google_suggest.php

<?php
function getGoogleSuggest($q)
{

    $url = "http://www.google.com/complete/search?hl=en&js=true&qu=" . $q;
    return file_get_contents($url);
}
?>

<?php echo getGoogleSuggest($_POST['q']) ?>

注:
a。 Google Suggest API 返回的是一个代码格式的文本信息,如下:
sendRPCDone(frameElement, "", new Array(), new Array(), new Array(""));
所以我们再前台接受到这个文本信息之后,应该写一个sendRPCDone的函数来做进一步信息处理(比如说列表出查询结果)。

3) 前台文本处理代码:

    <script type="text/javascript">
        var req;
        function GetSuggestion()
        {
            req = false;
            var f = document.QForm;

            // branch for native XMLHttpRequest object
            if(window.XMLHttpRequest)
            {
                try
                {
                    req = new XMLHttpRequest();
                }
                catch(e)
                {
                    req = false;
                }
            }
            else if(window.ActiveXObject) // branch for IE/Windows ActiveX version
            {
                try
                {
                    req = new ActiveXObject("Msxml2.XMLHTTP");
                }
                catch(e)
                {
                    try
                    {
                        req = new ActiveXObject("Microsoft.XMLHTTP");
                    }
                    catch(e)
                    {
                        req = false;
                    }
                }
            }
            if(req)
            {
                var url = "google_suggest.php";
       
                req.onreadystatechange = processReqChange;
                req.open("POST", url, true);

                req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                req.setRequestHeader("Method", "POST " + url + " HTTP/1.1");
                req.send("q=" + escape(document.QForm.qtext.value));
            }
           

        }
       
        function processReqChange()
        {
            if(req.readyState == 4) // only if req shows "loaded"
            {
                         if (req.status == 200) // only if "OK"
                         {
                                 x = req.responseText;
                                 eval(x);
  
                       }
                         else
                         {
                                 alert("There was a problem retrieving the XML data:\n" + req.statusText);
                         }
            }
            else if(req.readyState == 2)
            {
            }
        }
       
        function sendRPCDone(frameElement, qString, arr1, arr2, arr3)
        {
       
            var suggest_results = eval(arr1);
            var counts = eval(arr2);
            var htmlstr = "<TABLE cellspacing=4 border=0>";
            for (var i=0; i < suggest_results.length; i++)
            {
                htmlstr += "<tr><td><a href=\"javascript:self.location=\'http://www.google.com/search?hl=en&q=" + suggest_results[i] + "&btnG=Google+Search\'\">" + suggest_results[i] + "</a></td>";
                htmlstr += "<TD width=200><font color= 228b22>" + counts[i] + "</font></TD></TR>"
                    
            }
            htmlstr += "</TABLE>";
            document.getElementById("google_suggest_target").innerHTML = htmlstr;
       
        }
       
        </script>

4。家庭作业 :)

一定要自己写一些代码,才能巩固知识:)
题目:
我们经常用del.icio.us来收藏我们喜欢的网站或者文章,并加一些类似读书笔记的注释。那么我们怎么利用del.icio.us提供的API来访问我们的读书笔记信息,并显示在自己的Blog里呢?
提示:
1。你要有一个del.icio.us的账号,并且已经有所网页收藏作为实验数据:)
2。API URL 是 "http://del.icio.us/feeds/json/" + "你的账号名";自己参看一下,看返回什么样的格式文本。另外,如果要限制返回的记录数,可以加"?count=10"这样的参数。


最后,祝大家中秋愉快!

---------------------------完----------------------------




posted on 2006-10-07 07:05 Dedian 阅读(2234) 评论(2)  编辑  收藏 所属分类: Java Memo
评论:
  • # re: Ajax 浅谈  坏男孩 Posted @ 2006-10-07 12:57
    佩服楼主十月一期间仍然写博啊!  回复  更多评论   

  • # re: Ajax 浅谈  123bingbing Posted @ 2006-10-11 10:24
    如果你是深藏不露的编程高手,www.mylinux.com不仅让你有一展身手的好机会,更能赢得一份额外收入!
      回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
 
Copyright © Dedian Powered by: 博客园 模板提供:沪江博客