Ajax - 基础

Ajax技术,在2005年第一次正式出现, 是web2.0时代的标志,推动web开发技术向纵深发展。

XMLHttpRequest对象

XMLHttpRequest对象是Ajax的基础,在JavaScript中,XMLHttpRequest用于在后台与服务器交换数据,使浏览器可以在不重载整个页面的情况下,进行局部的数据更新。

创建XMLHttpRequest:

var xhr = new XMLHttpRequest();
// 所有的浏览器实现的XMLHttpRequest对象都踢动相同的接口与方法

创建open()方法建立一个HTTP请求:

// method:HTTP 请求方法,必要参数,值包括GET、POST、HEAD,不区分大小写;
// url: 请求的URL字符串,必选参数,大部分浏览器仅支持同源请求;
// async: 指定请求是否为异步方式,默认true,如果设置为FALSE,当状态改变时会立即调用onreadystatechange属性指定的回调函数;
// username: 可选参数,如果服务器需要验证,username指定用户名,如果未指定,当服务器需要验证时,会弹出验证窗口
// password:可选参数,验证信息中的密码,如果username参数为空,password的值会被忽略
xhr.open(method,url,async,username,password);

使用send()方法发送请求:

// 参数body表示将通过该请求发动的数据,如果不传递信息,可以设置为null或者省略不填
xhr.send(body);

发送请求后,使用XMLHttpRequest对象的responseBody、responseStream、responseText、responseXML属性接收相应数据。

GET和POST请求

最常见的客户端传递参数的方式:get请求和post请求。
POST请求是向服务器传送数据,请求传送的数据量较大,一般默认为不受限制;GET请求是从服务器获取数据,请求传送的数据量较小。

发送GET请求

实现方法: 将包含查询字符串的URL传入open方法,设置open方法的第一个参数为GET。
优点:请求简洁、方便,适用于简单字符串。
缺点:不适用于大容量或者加密数据。

GET请求示例:

<input name="submit" type="button" id="submit" value="向服务器发出请求" />
<script>
    window.onload = function () {  //页面初始化
        var b = document.getElementsByTagName("input")[0];
        b.onclick = function () {
        	// 查询字符串通过“?”作为前缀附加在URL的末尾,可以通过“&”连接多个键值对作为查询参数
            var url = "server.php?callback=functionName"//设置查询字符串
            var xhr = createXHR();  //实例化XMLHttpRequest 对象
            xhr.open("GET", url, false);  //建立连接,要求同步响应
            xhr.send(null);  //发送请求
            console.log(xhr.responseText);  //接收数据
        }
    }
</script>
发送POST请求

优点:请求允许发送任意类型、任意长度的数据,通常用于表单的提交。
方法:使用send()进行传递,不以字符串的方式传递.

// post字符串的格式和get字符串相同
send("userName = Tom & password = 123456");

POST 请求示例:

window.onload = function () {  //页面初始化
    var b = document.getElementsByTagName("input")[0];
    b.onclick = function () {
        var url = "server.php";  //设置请求的地址
        var xhr = createXHR();  //实例化XMLHttpRequest 对象
        xhr.open("POST", url, false);  //建立连接,要求同步响应
        //设置为表单方式提交,一般使用POST请求必须设置这一项,否者服务器无法识别传递的数据
        xhr.setRequestHeader ('Content-type', 'application/x-www-form-urlencoded');  
        xhr.send("callback=functionName");  //发送请求
        console.log(xhr.responseText);  //接收数据
    }
}

JSON转换为字符串
get和post方法都是以名值对的字符串格式发动数据的,下面提供一个在C语言中文网学到的工具函数,这个函数能将数据转换为串行格式字符串并返回:

//把JSON数据转换为串行字符串
//参数:data表示数组或对象类型的数据
//返回值:串行字符串
function JSONtoString (data) {
    var a = [];  //临时数组
    if (data.constructor == Array) {  //处理数组
        for (var i = 0; i < data.length; i ++) {
            a.push(data[i].name + "=" + encodeURIComponent(data[i].value));
        }
    } else {  //处理对象
        for (var i in data) {
            a.push(i + "=" + encodeURIComponent(data[i]));
        }
    }
    return a.join("&");  //把数组转换为串行字符串,并返回
}

XMLHttpRequest.readyState跟踪异步请求的状态

当Ajax请求被发送到服务器时,我们需要根据请求响应状态执行一定的操作,XMLHttpRequest对象的状态信息存储在readyState属性中。

异步响应状态

使用readyState属性可以实时跟踪异步响应状态
每当readyState属性改变时,会触发readystatechange事件,然后将响应的处理代码放在onreadystatechange事件处理函数中。

返回值说明
0未初始化。表示对象已经建立,尚未初始化,尚未调用open方法
1已初始化。表示对象已经建立,已经初始化,尚未调用open方法
2发送数据。表示已经调用了send方法,但是当前请求状态以及HTTP头未知
3数据传送中。已经接收部分数据,因为响应以及HTTP头不安全,这是通过responseBody和responseText获取部分数据会出现错误
4完成。数据接收完毕,这是可以通过responseBody 和 responseText获取完整响应数据

如果readState属性值为4,说明响应完毕,可以安全的读取响应数据。
更安全的方法:监测HTTP状态码,只有HTTP状态码为200时,说明HTTP响应顺利完成。

中止请求

使用abort()方法中止正在进行中的请求:

xhr.onreadystatechange = function () {};  //清理事件响应函数
xhr.abort();  //中止请求

中止请求的注意事项:

  • 调用abort方法前,需要先清除onreadystatechange事件处理函数,因为IE和Mozilla浏览器在中止请求后也会激活这个事件处理函数。
  • 如果给onreadystatechange属性设为null,在IE浏览器中会发生异常,所以需要设置为空函数。

Ajax解析返回的数据(多种格式)

XMLHttpRequest对象通过responseBody、responseText、responseStream或者responseXML属性获取响应信息,这些属性都是只读属性。

响应信息说明
responseBody将响应信息正文以 Unsigned Byte 数组形式返回
responseText以 ADO Stream 对象的形式返回响应信息
responseStream将响应信息作为字符串返回
responseXML将响应信息格式化为 XML 文档格式返回
纯文本

简短的信息,可以使用纯文本格式进行响应。
缺点:传递过程中易丢失,且无法检测信息的完整性

var xhr = new XMLHttpRequest(); // 实例化XMLHttpRequest对象
xhr.open("GET", "server.txt", true); // 建立连接,要求异步响应
xhr.onreadystatechange = function () { // 绑定响应状态事件监听函数
	if(xhr.readyState === 4){ // 监听readyState属性变化
		if (xhr.status == 200 || xhr.status == 0) {  //监听HTTP状态码
            var info = xhr.responseText;
            if (info == "true") console.log("文本信息传输完整");  //检测信息是否完整
            else console.log("文本信息可能存在丢失");
        }
	}
}
xhr.send(); // 发送请求
XML格式

XML格式更加通用,如果需要协作开发且项目比较庞杂,可以使用这一格式。

服务器端的XML文档:

<?xml version="1.0" encoding="utf-8"?>
<the>XML 数据</the>
<input name="submit" type="button" id="submit" value="向服务器发出请求" />
<script>
    window.onload = function () {  //页面初始化
        var b = document.getElementsByTagName("input")[0];
        b.onclick = function () {
            var xhr = createXHR();  //实例化XMLHttpRequest对象
            xhr.open("GET", "server.xml", true);  //建立连接,要求异步响应
            xhr.onreadystatechange = function () {  //绑定响应状态事件监听函数
                if (xhr.readyState == 4) {  //监听readyState状态
                    if (xhr.state == 200 || xhr.status == 0) {  //监听HTTP状态码
                        var info = xhr.responseXML;
                        console.log(info.getElementsByTagName("the")[0].firstChild.data);  //返回元信息字符串“XML 数据”
                    }
                }
            }
            xhr.send();  //发送请求
        }
    }
</script>
HTML格式
<table border="1" width="100%">
    <tr><td>RegExp.exec()</td><td>通用的匹配模式</td></tr>
    <tr><td>RegExp.test()</td><td>检测一个字符串是否匹配某个模式</td></tr>
</table>
<input name="submit" type="button" id="submit" value="向服务器发出请求" />
<script>
    window.onload = function () {  //页面初始化
        var b = document.getElementsByTagName("input")[0];
        b.onclick = function () {
            var xhr = createXHR();  //实例化XMLHttpRequest对象
            xhr.open("GET", "server.xml", true);  //建立连接,要求异步响应
            xhr.onreadystatechange = function () {  //绑定响应状态事件监听函数
                if (xhr.readyState == 4) {  //监听readyState状态
                    if (xhr.state == 200 || xhr.status == 0) {  //监听HTTP状态码
                        var o = document.getElementById("grid");
                        o.innerHTML = xhr.responseText;  //直接插入到页面中
                    }
                }
            }
            xhr.send();  //发送请求
        }
    }
</script>
JSON格式

使用responseText获取JSON格式的字符串,使用eval()方法解析为本地JavaScript脚本,再从数据对象中读取信息。

{ user : "css8", pass : "123456", email : "css8@123.cn" }
<input name="submit" type="button" id="submit" value="向服务器发出请求" />
<script>
    window.onload = function () {  //页面初始化
        var b = document.getElementsByTagName("input")[0];
        b.onclick = function () {
            var xhr = createXHR();  //实例化XMLHttpRequest对象
            xhr.open("GET", "server.xml", true);  //建立连接,要求异步响应
            xhr.onreadystatechange = function () {  //绑定响应状态事件监听函数
                if (xhr.readyState == 4) {  //监听readyState状态
                    if (xhr.state == 200 || xhr.status == 0) {  //监听HTTP状态码
                        var info = xhr.responseText;
                        var o = eval("(" + info + ")");  //调用eval()把字符串转换为本地脚本
                        console.log(info);  //显示JSON对象字符串
                        console.log(o.user);  //读取对象属性值,返回字符串“css8”
                    }
                }
            }
            xhr.send();  //发送请求
        }
    }
</script>

eval()方法解析JSON字符串存在安全隐患。如果 JSON 字符串中包含恶意代码,在调用回调函数时可能会被执行。
解决方法:先对 JSON 字符串进行过滤,屏蔽掉敏感或恶意代码。
不过,确信所响应的 JSON 字符串是安全的,没有被人恶意攻击,那么可以使用 eval() 方法解析 JSON 字符串。

JavaScript脚本

不建议使用JavaScript作为响应格式

// 示例js脚本
function () {
    var d = new Date();
    return d.toString();
}

客户端执行下面的请求,通过responseText获取响应信息,并用eval()把字符串转换为脚本
使用eval()方法时,在字符串前后附加两个小括号,一个用来包裹函数体,一个表示调用函数(立即执行函数

<input name="submit" type="button" id="submit" value="向服务器发出请求" />
<script>
    window.onload = function () {  //页面初始化
        var b = document.getElementsByTagName("input")[0];
        b.onclick = function () {
            var xhr = createXHR();  //实例化XMLHttpRequest对象
            xhr.open("GET", "server.xml", true);  //建立连接,要求异步响应
            xhr.onreadystatechange = function () {  //绑定响应状态事件监听函数
                if (xhr.readyState == 4) {  //监听readyState状态
                    if (xhr.state == 200 || xhr.status == 0) {  //监听HTTP状态码
                        var info = xhr.responseText;
                        var o = eval("(" + info + ")" + "()");  //用eval()把字符串转换为脚本
                        console.log(o);  //返回客户端当前信息
                    }
                }
            }
            xhr.send();  //发送请求
        }
    }
</script>

获取和设置HTTP报头消息

HTTP请求和响应都包含一组头部消息。

  • 获取响应头部消息:getAllResponseHeaders();
  • 获取指定的HTTP头部消息,参数为获取头部的名称:getResponseHeader(“Header-name”);
var xhr = new XMLHttpRequest();
var url = "server.txt";
xhr.open("GET", url, true);
xhr.onreadystatechange = function () {
    if (xhr.readyState == 4 && xhr.status == 200) {
        console.log(xhr.getAllResponseHeaders());
    }
}
xhr.send(null);
  • 在发送请求中设置各种头部消息:xhr.setResponseHeader("Header-name", "value");,Header-name表示头部消息的名称,value表示消息的具体值
  • 使用POST方法传递表单数据时,可以设置如下头部消息:xhr.setResponseHeader("Content-Type", "application/x-www-form-urlencoded");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值