JavaScript异步Ajax技术详解:从原理到实战
本文详细解析JavaScript中Ajax技术的实现原理,涵盖XMLHttpRequest对象的创建、GET与POST请求的区别、异步处理机制以及响应状态码的监听。通过具体代码示例,指导开发者如何在现代浏览器及旧版IE中正确发送和处理服务器数据,实现网页的局部无刷新更新。
一、什么是 AJAX ?
AJAX 全称为异步 JavaScript 和 XML。这是一种用于构建快速动态网页的技术方案。
AJAX 允许网页在后台与服务器进行少量数据交换,从而实现网页的异步更新。这意味着用户可以在不重新加载整个页面的情况下,仅更新页面的部分内容。相比之下,传统网页在需要更新内容时,必须重新加载整个页面。
市面上有许多应用 AJAX 技术的典型案例,例如新浪微博、Google 地图以及开心网等。
1、AJAX是基于现有的Internet标准
AJAX 建立在现有的 Internet 标准之上,并综合运用了以下技术:
- XMLHttpRequest 对象(用于与服务器异步交换数据)
- JavaScript/DOM(用于信息的显示与交互)
- CSS(用于为数据定义样式)
- XML(用于作为数据传输的格式)
需要注意的是,AJAX 应用程序与具体的浏览器及平台无关。
2、AJAX 工作原理

二、AJAX - 创建 XMLHttpRequest 对象
1、XMLHttpRequest 对象
XMLHttpRequest 是 AJAX 技术的核心基础。所有现代浏览器均原生支持 XMLHttpRequest 对象,而在 IE5 和 IE6 中则需使用 ActiveXObject。
XMLHttpRequest 的主要作用是在后台与服务器交换数据,从而实现在不重新加载整个网页的前提下,对网页的特定部分进行更新。
2、创建 XMLHttpRequest 对象
所有现代浏览器(包括 IE7 及以上版本、Firefox、Chrome、Safari 以及 Opera)均内置了 XMLHttpRequest 对象。
创建 XMLHttpRequest 对象的标准语法如下:
variable=new XMLHttpRequest();对于老版本的 Internet Explorer(即 IE5 和 IE6),则需使用 ActiveX 对象:
variable=new ActiveXObject("Microsoft.XMLHTTP");为了确保代码兼容所有现代浏览器,包括 IE5 和 IE6,建议先检查浏览器是否支持 XMLHttpRequest 对象。如果支持,则创建 XMLHttpRequest 对象;如果不支持,则创建 ActiveXObject:
var xmlhttp;
if (window.XMLHttpRequest)
{
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlhttp=new XMLHttpRequest();
}
else
{
// IE6, IE5 浏览器执行代码
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}三、向服务器发送请求请求
1、向服务器发送请求
XMLHttpRequest 对象用于与服务器进行数据交换。
若要将请求发送至服务器,需使用 XMLHttpRequest 对象的 open() 和 send() 方法:
xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();相关方法说明:
open(method,url,async):用于规定请求的类型、URL 地址以及是否采用异步方式处理请求。
- method:指定请求的类型,可选 GET 或 POST。
- url:指定服务器端文件的位置。
- async:指定是否异步处理,true 表示异步,false 表示同步。
send(string):将请求发送至服务器。其中 string 参数仅在使用 POST 请求时有效。
注意:open() 方法中的 url 参数指向的是服务器端文件的地址:
xmlhttp.open("GET","ajax_test.html",true);该文件可以是任何类型,例如 .txt 或 .xml,也可以是服务器脚本文件,如 .asp 或 .php(在返回响应之前,服务器端可执行相应任务)。
2、GET 还是 POST?
与 POST 请求相比,GET 请求更为简单且速度更快,且在大多数场景下均可使用。
然而,在以下情况中,建议使用 POST 请求:
- 无法使用缓存文件(例如需要更新服务器上的文件或数据库)。
- 向服务器发送大量数据(POST 请求没有数据量限制)。
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定且更可靠。
3、GET 请求
一个简单的 GET 请求示例如下:
xmlhttp.open("GET","/try/ajax/demo_get.php",true);
xmlhttp.send();在上述示例中,浏览器可能会返回缓存的结果。
为避免这种情况,可向 URL 中添加一个唯一的 ID:
xmlhttp.open("GET","/try/ajax/demo_get.php?t=" + Math.random(),true);
xmlhttp.send();如果希望使用 GET 方法发送额外信息,可将信息附加到 URL 中:
xmlhttp.open("GET","/try/ajax/demo_get2.php?fname=Henry&lname=Ford",true);
xmlhttp.send();4、POST 请求
一个简单的 POST 请求示例如下:
xmlhttp.open("POST","/try/ajax/demo_post.php",true);
xmlhttp.send();若需像 HTML 表单那样发送 POST 数据,请使用 setRequestHeader() 方法添加 HTTP 头部信息。随后在 send() 方法中指定希望发送的数据:
xmlhttp.open("POST","/try/ajax/demo_post2.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Henry&lname=Ford");5、异步 - True 或 False?
AJAX 全称为异步 JavaScript 和 XML(Asynchronous JavaScript and XML)。
若 XMLHttpRequest 对象用于 AJAX,其 open() 方法中的 async 参数必须设置为 true:
xmlhttp.open("GET","ajax_test.html",true);对于 Web 开发人员而言,发送异步请求是一项巨大的进步。许多在服务器端执行的任务耗时较长,而在 AJAX 出现之前,这可能导致应用程序挂起或停止响应。
通过 AJAX,JavaScript 无需等待服务器响应,而是可以:
- 在等待服务器响应时执行其他脚本。
- 当响应就绪后,对响应进行处理。
当使用 async=true 时,需规定在响应处于 onreadystatechange 事件中的就绪状态时执行的函数:
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","/try/ajax/ajax_info.txt",true);
xmlhttp.send();注意:当使用 async=false 时,请勿编写 onreadystatechange 函数,而应将代码放置在 send() 语句之后即可:
xmlhttp.open("GET","/try/ajax/ajax_info.txt",false);
xmlhttp.send();
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;四、AJAX - 服务器 响应
如需获取来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。
- responseText:获取字符串形式的响应数据。
- responseXML:获取 XML 形式的响应数据。
1、responseText 属性
如果来自服务器的响应并非 XML 格式,请使用 responseText 属性。
responseText 属性返回字符串形式的响应,因此您可以按以下方式使用:
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;2、responseXML 属性
如果来自服务器的响应是 XML,且需要作为 XML 对象进行解析,请使用 responseXML 属性:
xmlDoc=xmlhttp.responseXML;
txt="";
x=xmlDoc.getElementsByTagName("ARTIST");
for (i=0;i<x.length;i++)
{
txt=txt + x[i].childNodes[0].nodeValue + "<br>";
}
document.getElementById("myDiv").innerHTML=txt;五、AJAX - onreadystatechange 事件
当请求被发送到服务器时,我们需要根据响应执行相应的任务。
每当 readyState 属性发生变化时,就会触发 onreadystatechange 事件。
readyState 属性保存了 XMLHttpRequest 的状态信息。
1、XMLHttpRequest 对象的三个重要的属性:
1、onreadystatechange:存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。
2、readyState:保存 XMLHttpRequest 的状态,取值从 0 到 4 发生变化。
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成,且响应已就绪
3、status:状态码。200 表示 "OK";404 表示未找到页面。
在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理准备时所执行的任务。
当 readyState 等于 4 且状态为 200 时,表示响应已就绪:
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}注意:onreadystatechange 事件会被触发 4 次(状态码从 0 到 4),分别对应:0-1、1-2、2-3、3-4,即 readyState 的每次变化。
2、使用回调函数
回调函数是一种以参数形式传递给另一个函数的函数。
如果您的网站上存在多个 AJAX 任务,建议编写一个标准的函数来创建 XMLHttpRequest 对象,并为每个 AJAX 任务调用该函数。
该函数调用应包含 URL 以及发生 onreadystatechange 事件时执行的任务(每次调用可能不尽相同):
function myFunction()
{
loadXMLDoc("/try/ajax/ajax_info.txt",function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
});
}六、javascript 脚本化的HTTP----ajax的基石
1、建XMLHttpRequest对象
// This is a list of XMLHttpRequest-creation factory functions to try
HTTP._factories = [
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
];
// When we find a factory that works, store it here.
HTTP._factory = null;
// Create and return a new XMLHttpRequest object.
//
// The first time we're called, try the list of factory functions until
// we find one that returns a non-null value and does not throw an
// exception. Once we find a working factory, remember it for later use.
//
HTTP.newRequest = function() {
if (HTTP._factory != null) return HTTP._factory();
for(var i = 0; i < HTTP._factories.length; i++) {
try {
var factory = HTTP._factories[i];
var request = factory();
if (request != null) {
HTTP._factory = factory;
return request;
}
}
catch(e) {
continue;
}
}
// If we get here, none of the factory candidates succeeded,
// so throw an exception now and for all future calls.
HTTP._factory
= function() {
throw new Error("XMLHttpRequest not supported");
}
HTTP._factory(); // Throw an error
}2、Get请求
HTTP.get = function(url, callback, options) {
var request = HTTP.newRequest();
var n = 0;
var timer;
if (options.timeout)
timer = setTimeout(function() {
request.abort();
if (options.timeoutHandler)
options.timeoutHandler(url);
},
options.timeout);
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (timer) clearTimeout(timer);
if (request.status == 200) {
callback(HTTP._getResponse(request));
}
else {
if (options.errorHandler)
options.errorHandler(request.status,
request.statusText);
else callback(null);
}
}
else if (options.progressHandler) {
options.progressHandler(++n);
}
}
var target = url;
if (options.parameters)
target += "?" + HTTP.encodeFormData(options.parameters)
request.open("GET", target);
request.send(null);
};1、GET工具
//getText()工具
HTTP.getText = function(url, callback) {
var request = HTTP.newRequest();
request.onreadystatechange = function() {
if(request.readyState == 4 && request.status == 200) {
callback(request.responseText);
}
}
request.open("GET", url);
request.send(null);
}
//getXML()工具
HTTP.getXML = function(url, callback) {
var request = HTTP.newRequest();
request.onreadystatechange = function() {
if(request.readyState == 4 && request.status == 200) {
callback(request.responseXML);
}
}
request.open("GET", url);
request.send(null);
}3、POST请求
/**
* Send an HTTP POST request to the specified URL, using the names and values
* of the properties of the values object as the body of the request.
* Parse the server's response according to its content type and pass
* the resulting value to the callback function. If an HTTP error occurs,
* call the specified errorHandler function, or pass null to the callback
* if no error handler is specified.
**/
HTTP.post = function(url, values, callback, errorHandler) {
var request = HTTP.newRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200) {
callback(HTTP._getResponse(request));
}
else {
if (errorHandler) errorHandler(request.status,
request.statusText);
else callback(null);
}
}
}
request.open("POST", url);
// This header tells the server how to interpret the body of the request.
request.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
// Encode the properties of the values object and send them as
// the body of the request.
request.send(HTTP.encodeFormData(values));
};4、获取Http头(包括解析头部数据)
HTTP.getHeaders = function(url, callback, errorHandler) {
var request = HTTP.newRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
if (request.status == 200) {
callback(HTTP.parseHeaders(request));
}
else {
if (errorHandler) errorHandler(request.status,
request.statusText);
else callback(null);
}
}
}
request.open("HEAD", url);
request.send(null);
};
// Parse the response headers from an XMLHttpRequest object and return
// the header names and values as property names and values of a new object.
HTTP.parseHeaders = function(request) {
var headerText = request.getAllResponseHeaders(); // Text from the server
var headers = {}; // This will be our return value
var ls = /^"s*/; // Leading space regular expression
var ts = /"s*$/; // Trailing space regular expression
// Break the headers into lines
var lines = headerText.split(""n");
// Loop through the lines
for(var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line.length == 0) continue; // Skip empty lines
// Split each line at first colon, and trim whitespace away
var pos = line.indexOf(':');
var name = line.substring(0, pos).replace(ls, "").replace(ts, "");
var value = line.substring(pos+1).replace(ls, "").replace(ts, "");
// Store the header name/value pair in a JavaScript object
headers[name] = value;
}
return headers;
};5、私有方法
1、获取表单数据:
/**
* Encode the property name/value pairs of an object as if they were from
* an HTML form, using application/x-www-form-urlencoded format
*/
HTTP.encodeFormData = function(data) {
var pairs = [];
var regexp = /%20/g; // A regular expression to match an encoded space
for(var name in data) {
var value = data[name].toString();
// Create a name/value pair, but encode name and value first
// The global function encodeURIComponent does almost what we want,
// but it encodes spaces as %20 instead of as "+". We have to
// fix that with String.replace()
var pair = encodeURIComponent(name).replace(regexp,"+") + '=' +
encodeURIComponent(value).replace(regexp,"+");
pairs.push(pair);
}
// Concatenate all the name/value pairs, separating them with &
return pairs.join('&');
};2、获取响应:
HTTP._getResponse = function(request) {
switch(request.getResponseHeader("Content-Type")) {
case "text/xml":
return request.responseXML;
case "text/json":
case "text/javascript":
case "application/javascript":
case "application/x-javascript":
return eval(request.responseText);
default:
return request.responseText;
}
}6、使用:
//提交表单,调用POST方法
var uname = document.getElementById("username");
var usex = document.getElementById("sex");
var formdata = {'username':'tom','sex':'男'};
HTTP.post("./test.php",formdata, doFun, errorFun);
//请求获取指定的URL的headers
HTTP.getHeaders("./a.html", doFun, errorFun);到此这篇关于JavaScript实现异步Ajax的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持本站。
JS split切割后出现空字符串怎么过滤
2026-11-05 16:00:30
在 React 或 Vue 项目中封装使用 JS 节流防抖
2026-11-05 15:27:29
JavaScript中怎么将带小数的字符串转为整数?
2026-11-05 14:32:38
怎么用JavaScript策略模式重构电商促销计算逻辑?
2026-11-05 14:01:09
JS使用constructor判断数据类型可靠吗
2026-11-05 13:49:41
