Javascript 基础使用 Ajax

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript 基础使用 Ajax相关的知识,希望对你有一定的参考价值。

Ajax 是现代Web 应用程序开发的一项关键工具。它让你能向服务器异步发送和接收数据,然后用 javascript 解析。 Ajax 是 Asynchronous JavaScript and XML (异步JavaScript 与XML)的缩写。

Ajax 核心规范的名称继承于用来建立和发起请求的 Javascript 对象:XMLHttpRequest 。这个规范有两个等级。所有主流浏览器都实现了第一级,它代表了基础级别的功能。第二级扩展了最初的规范,纳入了额外的事件和一些功能来让它更容易与 form 元素协作,并且支持一些相关规范。

 

1. Ajax起步

Ajax 的关键在于 XMLHttpRequest 对象,而理解这个对象的方法是看个例子。下面代码展示了 XMLHttpRequest 对象的基本用法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用XMLHttpRequest对象</title>
</head>
<body>
<div>
    <button>apples</button>
    <button>bananas</button>
    <button>lemons</button>
</div>
<div id="target">
    Press a button
</div>

<script type="application/javascript">
    var buttons = document.getElementsByTagName("button");
    for(var i=0; i<buttons.length; i++){
        buttons[i].onclick = handleButtonPress;
    }

    //脚本会调用此函数以响应 button 控件的 click 事件
    function  handleButtonPress(e){
        //创建一个新的 XMLHttpRequest 对象
        var httpRequest = new XMLHttpRequest();
        //给 onreadystatechange 事件设置一个事件处理器
        httpRequest.onreadystatechange = handleResponse;
        //使用 open 方法来指定 HTTP 方法和需要请求的 URL (即告诉 httpRequest 对象你想要做的事)
        httpRequest.open("GET", e.target.innerHTML+".html");
        //这里没有向服务器发送任何数据,所以 send 方法无参数可用
        httpRequest.send();
    }

    //处理响应
    //一旦脚本调用了 send 方法,浏览器就会在后台发送请求到服务器。因为请求是在后台处理的,所以Ajax 依靠事件来通知这个请求的进展情况。
    function handleResponse(e){
        //当 onreadystatechange 事件被触发后,浏览器会把一个 Event 对象传递给指定的处理函数,target 属性则会被设为与此事件关联的XMLHttpRequest
        if(e.target.readyState == XMLHttpRequest.DONE && e.target.status == 200){ //请求成功
            document.getElementById("target").innerHTML = e.target.responseText; //显示被请求文档的内容
        }
    }
</script>
</body>
</html>

当某个按钮被按下后,示例中的脚本会载入另一个HTML文档,并让它称为div元素的内容。其他的文档一共三个,分别对应button元素上的说明标签:apples.html、lemons.html 和 bananas.html。

此例的显示效果如下图所示:

这三个额外的文档非常简单,其中apples.html 如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Apples</title>
    <style>
        img { float:left;padding:2px;margin:5px;border: medium double black;background-color: lightgrey; width: 100px;height: 100px;}
    </style>
</head>
<body>
<p>
    <img src="../imgs/apple.png"/>
    Page for apples.
</p>
</body>
</html>

随着用户点击各个水果按钮,浏览器会异步执行并取回所请求的文档,而主文档不会被重新加载。这就是典型的 Ajax 行为。

 

2. 使用 Ajax 事件

建立和探索一个简单的示例之后,可以开始深入了解 XMLHttpRequest 对象支持的功能,以及如何在请求中使用它们了。起点就是第二级规范里定义的那些额外事件:

这些事件大多数会在请求的某一特定时间点上触发。 readystatechange 和 progress 这两个事件是例外,它们可以多次触发以提供进度更新。

调度这些事件时,浏览器会对 readystatechange 事件使用常规的 Event 对象,对其他事件则使用 ProgressEvent 对象。 ProgressEvent 对象定义了 Event 对象的所有成员,并增加了下图中介绍的这些成员:

下面代码展示了如何使用这些事件: 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用XMLHttpRequest定义的一次性事件</title>
    <style>
        table {margin: 10px;border-collapse: collapse; float: left;}
        div{margin: 10px;}
        td,th{padding: 4px;}
    </style>
</head>
<body>
<div>
    <button>apples</button>
    <button>bananas</button>
    <button>lemons</button>
</div>
<table id="events" border="1"></table>
<div id="target">
    Press a button
</div>

<script type="application/javascript">
    var buttons = document.getElementsByTagName("button");
    for(var i=0; i<buttons.length; i++){
        buttons[i].onclick = handleButtonPress;
    }

    var httpRequest;
    function  handleButtonPress(e){
        clearEventDetails();
        httpRequest = new XMLHttpRequest();
        httpRequest.onreadystatechange = handleResponse;

        httpRequest.onerror = handleError;
        httpRequest.onload = handleLoad;;
        httpRequest.onloadend = handleLoadEnd;
        httpRequest.onloadstart = handleLoadStart;;
        httpRequest.onprogress = handleProgress;

        httpRequest.open("GET", e.target.innerHTML+".html");
        httpRequest.send();
    }

    function handleResponse(e){
        displayEventDetails("readystate("+httpRequest.readyState+")")
        if(e.target.readyState == XMLHttpRequest.DONE && e.target.status == 200){
            document.getElementById("target").innerHTML = e.target.responseText;
        }
    }

    function handleError(e){ displayEventDetails("error",e);}
    function handleLoad(e){ displayEventDetails("load",e);}
    function handleLoadEnd(e){ displayEventDetails("loadend",e);}
    function handleLoadStart(e){ displayEventDetails("loadstart",e);}
    function handleProgress(e){ displayEventDetails("progress",e);}

    function clearEventDetails(){
        document.getElementById("events").innerHTML = "<tr><th>Event</th><th>lengthComputable</th><th>loaded</th><th>total</th>";
    }

    function displayEventDetails(eventName,e){
        if(e){
            document.getElementById("events").innerHTML
                    +="<tr><td>"+eventName+"</td><td>"+ e.lengthComputable+"</td><td>"+ e.loaded+"</td><td>"+ e.total+"</td></tr>";
        }else {
            document.getElementById("events").innerHTML += "<tr><td>"+eventName+"</td><td>NA</td><td>NA</td><td>NA</td></tr>";
        }
    }
</script>
</body>
</html>

这是之前示例的一种变型,为一些事件注册了处理函数,并在一个 table 元素里为处理的每个事件都创建了一条记录。从下图中可以看到 Firefox 浏览器是如何触发这些事件的。

3. 处理错误

使用 Ajax 时必须留心两类错误。它们之间的区别源于视角不同。

第一类错误是从 XMLHttpRequest 对象的角度看到的问题:某些因素阻止了请求发送到服务器。例如 DNS 无法解析主机名,连接请求被拒绝,或者URL无效。

第二类问题是从应用程序的角度看到的问题,而非 XMLHttpRequest 对象。它们发生于请求成功发送至服务器,服务器接收请求、进行处理并生成响应,但该响应并不指向你期望的内容。例如,如果请求的URL 不存在,这类问题就会发生。

有三种方式可以处理这些错误,如下面代码所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>处理Ajax错误</title>
</head>
<body>
<div>
    <button>apples</button>
    <button>bananas</button>
    <button>lemons</button>
    <button id="badhost">Bad Host</button>
    <button id="badurl">Bad URL</button>
</div>
<div id="target">Press a button</div>
<div id="errormsg"></div>
<div id="statusmsg"></div>

<script type="application/javascript">
    var buttons = document.getElementsByTagName("button");
    for(var i = 0; i < buttons.length; i++){
        buttons[i].onclick = handleButtonPress;
    }

    var httpRequest;

    function handleButtonPress(e){
        clearMessages();
        httpRequest = new XMLHttpRequest();
        httpRequest.onreadystatechange = handleResponse;
        httpRequest.onerror = handleError;
        try{
            switch(e.target.id){
                case "badhost":
                    httpRequest.open("GET","http://www.ycdoitt.com/nopage.html")
                    break;
                case "badurl":
                    httpRequest.open("GET","http://")
                    break;
                default:
                    httpRequest.open("GET", e.target.innerHTML + ".html")
                    break;
            }
            httpRequest.send();
        }catch(error){
            displayErrorMsg("try/catch",error.message+"("+error.name+")")
        }
    }

    function handleError(e){
        displayErrorMsg("Error event",httpRequest.status + httpRequest.statusText);
    }

    function handleResponse(){
        if(httpRequest.readyState == 4){
            var target = document.getElementById("target");
            if(httpRequest.status == 200){
                target.innerHTML = httpRequest.responseText;
            }else{
                document.getElementById("statusmsg").innerHTML
                        = "Status:" + httpRequest.status +" "+ httpRequest.statusText;
            }
        }
    }

    function displayErrorMsg(src,msg){
        document.getElementById("errormsg").innerHTML = src + ": " +执行AJAX返回HTML片段中的JavaScript脚本

javascript AJAX片段

JavaScript-Tool-lhgDialog:动画示例

Thymeleaf - 如何交互和重新加载 Javascript?

AJAX 响应:数据(JSON、XML)还是 HTML 片段? [关闭]

ajax与 axios的基础讲解(附代码及接口)