Ajax是前端与后端交互最基础也最重要的技术之一。它的核心思想是:通过JavaScript在浏览器后台发送HTTP请求,拿到数据后局部更新页面,而不是让整个页面重新加载。围绕这个核心,不同的库封装出了不同形式的Ajax函数,其中jQuery的$.ajax使用最为广泛。想要真正用好它,就必须理解每个参数背后的含义,而不是照着别人的代码抄一遍。本文将从原生实现讲到jQuery封装,把常用参数一个一个拆开分析。

一、Ajax的本质:XMLHttpRequest对象
很多人一上来就学$.ajax,却不知道它底下是什么。实际上,无论jQuery还是axios,浏览器的Ajax能力都来自XMLHttpRequest这个内置对象。理解它的基本流程,有助于你在参数出错时判断问题出在哪一层。
原生写法分为四步:创建对象、配置请求、监听响应、发送请求。下面这段代码演示了一个最简单的GET请求:
// 第一步:创建XHR对象,老版本IE需要用ActiveXObject兼容
var xhr = new XMLHttpRequest();
// 第三步:先注册事件,监听状态变化
xhr.onreadystatechange = function () {
// readyState为4表示响应完成,status为200表示请求成功
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
};
// 第二步:配置请求方式、地址、是否异步
xhr.open('GET', '/api/user/list', true);
// 第四步:发送
xhr.send();
这段代码里的几个要点值得注意。open方法的第三个参数控制同步还是异步,几乎永远应该传true,传false会阻塞浏览器线程,页面会卡死直到请求返回,这已经被现代浏览器废弃。另外,onreadystatechange必须写在send之前注册,虽然某些浏览器允许事后注册,但规范上不能保证监听得到全部状态变化。
jQuery的$.ajax本质上就是把上面这套流程封装成一个配置对象,把回调拆成success、error、complete等字段,让代码结构更清晰。理解了这一层,后面看参数就不会觉得抽象了。
二、$.ajax核心参数逐一拆解
$.ajax接收一个配置对象,可配置的选项有二三十个,但日常开发中高频使用的其实就十来个。下面先看一个典型示例,再逐个说明:
$.ajax({
url: '/api/user/login', // 请求地址
type: 'POST', // 请求方式,也可写作method
data: { username: 'tom', pwd: '123456' }, // 发送到服务器的数据
dataType: 'json', // 预期服务器返回的数据类型
contentType: 'application/x-www-form-urlencoded', // 请求体编码类型
async: true, // 是否异步,默认true
timeout: 5000, // 超时时间,毫秒
success: function (res) {
console.log('成功', res);
},
error: function (xhr, status, err) {
console.log('失败', xhr.status, status, err);
},
complete: function (xhr, status) {
console.log('无论成败都执行');
}
});
url与type是最基础的两个参数。url支持相对路径和绝对路径,如果跨域则需要服务端配合CORS。type常用值有GET、POST、PUT、DELETE,对应RESTful风格的增删改查操作。type是method的别名,1.9.0之后建议统一使用method写法。
data参数的细节最多。GET请求时,data会被自动拼接成查询字符串附加到url后面;POST请求时则放进请求体。传入对象时jQuery会自动做URL编码,比如空格变成%20。如果你想发送JSON格式的请求体,就不能只传对象,必须配合contentType和JSON.stringify,这是最容易踩的坑,后面单独讲。
dataType告诉jQuery如何解析服务器返回的内容。设为json时,jQuery会把响应文本解析成JavaScript对象,success回调里拿到的直接就是对象而不是字符串。设为jsonp则走JSONP跨域方案。不设置时jQuery会根据响应头智能判断,但显式声明更稳妥。
success、error、complete三个回调的执行时机要分清:请求成功且解析通过走success;网络错误、超时、HTTP状态码非2xx、dataType解析失败都走error;而complete不管成败都会执行,适合做loading遮罩的隐藏这类清理工作。注意error回调的第一个参数是XHR对象,可以从xhr.status和xhr.responseText里拿到失败的具体信息。
三、POST提交JSON:contentType与processData的配合
前后端分离的项目里,服务端经常要求POST请求体是JSON格式。很多初学者直接把对象传给data,结果后端收到的要么是空,要么是乱码的表单字符串。原因在于jQuery默认行为是表单编码,也就是contentType默认为application/x-www-form-urlencoded,data里的对象会被序列化成username=tom&pwd=123456这种形式。
要发送JSON,需要两步配合:一是手动把对象转成JSON字符串,二是把contentType改成application/json。正确的写法如下:
$.ajax({
url: '/api/user/create',
method: 'POST',
contentType: 'application/json; charset=utf-8', // 声明请求体是JSON
data: JSON.stringify({ username: 'tom', age: 20 }), // 必须手动序列化
dataType: 'json',
success: function (res) {
console.log(res);
}
});
这里的关键是JSON.stringify不能省。如果直接传对象,jQuery会尝试表单序列化,嵌套对象会被拍平成奇怪的字段名,后端完全解析不出来。
再说说processData这个参数。它默认为true,表示jQuery自动处理data并转成查询字符串。但当你需要上传文件时,比如用FormData对象,就必须把它设为false,同时把contentType也设为false,让浏览器自动设置带分界符的multipart/form-data头,否则文件上传必定失败:
var fd = new FormData();
fd.append('file', fileInput.files[0]);
fd.append('desc', '头像文件');
$.ajax({
url: '/api/upload',
method: 'POST',
data: fd,
processData: false, // 禁止jQuery把FormData转成字符串
contentType: false, // 禁止jQuery手动设置contentType,交给浏览器
success: function (res) { console.log(res); }
});
这两个参数设为false的含义容易误解,它不是关闭功能,而是告诉jQuery不要插手数据的预处理,把控制权交还给开发者和浏览器本身。
四、异步回调与常见报错的排查思路
Ajax默认是异步的,这意味着$.ajax调用之后的代码会立刻执行,不会等待请求完成。一个经典错误是把请求结果赋值给外部变量然后在下一行使用:
var result;
$.ajax({
url: '/api/data',
async: true,
success: function (res) {
result = res; // 回调执行时机晚于下面的console.log
}
});
console.log(result); // undefined,因为请求还没回来
解决办法有两种:老老实实把后续逻辑写进success回调里,或者用Promise风格的链式调用。jQuery 1.5之后$.ajax返回一个Deferred对象,可以用.then().catch()的写法,也可以直接用await $.ajax(),代码可读性会好很多。
排查报错时建议分三步走。第一步看浏览器控制台的Network面板,确认请求到底发出去没有、状态码是多少。404说明地址不对,405说明请求方式和服务端要求不匹配,500是服务端内部错误,需要看后端日志。第二步如果状态码是0或提示CORS错误,基本是跨域问题,需要服务端设置Access-Control-Allow-Origin响应头,开发阶段也可以用代理转发绕过。第三步检查响应内容,如果success没触发而error里提示解析失败,多半是后端返回的不是合法JSON,比如返回的字符串两端多了空行或者夹着警告信息,这时可以临时把dataType去掉,用xhr.responseText看看原始内容。
掌握了这些参数的含义和排查方法,日常开发中百分之九十的Ajax问题都能自己定位。剩下的一些边缘场景,比如JSONP的原理、跨域携带Cookie需要设置xhrFields: { withCredentials: true },理解了本文的基础内容之后再去看官方文档,也会轻松许多。
Ajax函数Ajax参数XMLHttpRequest修改时间:2026-09-10 21:37:05