详解JavaScript中jQuery和Ajax以及JSONP的联合使用
本文深入解析jQuery中Ajax与JSONP的联合使用机制。详细对比GET与POST请求差异,阐述$.ajax()核心配置选项及简便方法,并重点讲解如何利用JSONP突破同源策略限制实现跨域数据交互,附带服务端与客户端完整代码示例及调试建议。
Ajax 基础概念
利用 XMLHttpRequest 对象,浏览器能够在不刷新整个页面的前提下与服务器进行数据交互,这种技术被称为 Ajax(Asynchronous JavaScript and XML)。Ajax 的应用能够显著提升用户的交互体验。
Ajax 请求由 JavaScript 代码发起,通过向指定 URL 发送请求,并在服务器返回响应时触发预设的回调函数来处理返回信息。由于该过程是异步进行的,页面中的其他 JavaScript 代码在请求期间可继续执行,不会造成阻塞。
jQuery 对 Ajax 提供了完善的支持,并封装了不同浏览器在 Ajax 支持上的差异。它不仅提供了功能完整的 $.ajax() 方法,还封装了 $.get()、$.getScript()、$.getJSON()、$.post() 以及 $().load() 等更为便捷的方法。
虽然被称为 Ajax,但许多 Ajax 应用实际上并不使用 XML,尤其是基于 jQuery 的应用。在实际开发中,更常见的数据格式是纯文本、HTML 以及 JSON(JavaScript Object Notation)。
受限于同源策略(即协议、域名、端口必须相同),普通的 Ajax 请求无法跨域执行。为了实现受限的跨域功能,通常需要借助 JSONP(JSON with Padding)等方案。 关于 Ajax 的一些重要概念
GET 与 POST 请求对比
GET 与 POST 是两种最常用的向服务器发送请求的方式,正确理解两者的区别对于 Ajax 开发至关重要。
GET 方法通常用于执行非破坏性操作,即仅从服务器获取信息而不修改服务器数据。例如,搜索查询服务通常使用 GET 请求。此外,GET 请求可能会被浏览器缓存,这可能导致一些不可预知的问题。一般情况下,GET 请求仅能通过查询字符串向服务器发送数据。
POST 方法通常用于在服务器上执行破坏性操作,即会修改服务器上的数据。例如,发布博客文章时通常使用 POST 请求。与 GET 请求不同,POST 请求不存在缓存问题。虽然 POST 请求也可以通过 URL 中的查询字符串提交数据,但不推荐这种做法,所有数据应与 URL 分开单独发送。
数据类型方面,jQuery 通常要求指明服务器返回的数据类型。某些情况下,数据类型已包含在方法名称中,如 $.getJSON();在其他情况下,它作为可配置对象的一部分,最终作为 $.ajax() 方法的参数。数据类型通常包括以下几种:
- text:纯文本,用于传输简单的字符串。
- html:用于传输一段 HTML 代码。
- script:用于向页面中添加脚本。
- json:传输已格式化的 JSON 对象,它可以包含字符串、数组或对象。
- jsonp:用于传输从其他域返回的 JSON 数据。
- xml:用于传输自定义的 XML 格式数据。
异步执行与回调处理
异步执行,Ajax 中的 A 代表异步(Asynchronous)。许多 jQuery 初学者可能对异步概念感到困惑,因为默认情况下 Ajax 请求就是异步的,服务器返回的信息并非立即获取。所有服务器返回的信息只能在回调函数中处理。例如以下这段代码是错误的:
var response;
$.get('foo.php', function(r) { response = r; });
console.log(response); // undefined!
正确的做法是在回调函数中处理服务器返回的数据,回调函数在 Ajax 请求成功完成时才被执行,此时才能获取到来自服务器的数据:
$.get('foo.php', function(response) { console.log(response); });
同源策略与 JSONP 跨域
同源策略及 JSONP,前文已述,通常情况下 Ajax 请求会被限制在相同协议(http 或 https)、相同端口、相同域名下才能正确执行。然而,HTML 的 <script> 标签不受此限制,它可以加载任何域下的脚本。jQuery 正是利用这一点实现了跨域执行 Ajax 的能力。
所谓 JSONP,是指其他域的服务器返回 JavaScript 代码。这段代码可以被加载到 HTML 中的 <script> 标签中,其中包含从其他域服务器返回的 JSON 数据,并以回调函数的形式提供。这样 jQuery 就避开了同源策略的限制,间接实现了跨域执行 Ajax 的能力。
Ajax 调试工具,现代浏览器如 Chrome 和 Safari,甚至 IE 都内置了调试工具,Firefox 也有功能强大的 FireBug 插件。借助这些调试工具,可以非常详细地查看 Ajax 的执行过程。 和 Ajax 相关的一些方法
$.ajax 核心配置详解
jQuery 提供了多种简便的 Ajax 方法,但它们的核心都是 $.ajax,因此必须正确理解 $.ajax。
jQuery 的 $.ajax 是创建 Ajax 请求最直接且有效的方法,其参数是一个 JavaScript 对象,我们可以在该对象中对 Ajax 进行非常详细的配置。此外,$.ajax 方法还可以分别定义 Ajax 请求成功和失败时的回调函数;且它以可配置对象作为参数的特性,使得我们可以在 Ajax 方法外配置该对象,然后再传入,这非常有助于实现代码复用。关于这个方法的详细文档:http://api.jquery.com/jQuery.ajax/
一个典型的示例如下:
$.ajax({
// 要请求的 URL
url : 'post.php',
// 要发给服务端的数据
// (将会转化为查询字符串,如:?id=123)
data : { id : 123 },
// 定义此 Ajax 请求是 POST 还是 GET
type : 'GET',
// 服务端返回的数据类型
dataType : 'json',
// Ajax 成功执行时的回调函数;
// 回调函数的参数即为服务端返回的数据
success : function(json) {
$('<h1/>').text(json.title).appendTo('body');
$('<div class="content"/>')
.html(json.html).appendTo('body');
},
// 如果 Ajax 执行失败;
// 将返回原始错误信息以及状态码
// 传入这个回调函数中
error : function(xhr, status) {
alert('Sorry, there was a problem!');
},
// 这里是无论 Ajax 是否成功执行都会触发的回调函数
complete : function(xhr, status) {
alert('The request is complete!');
}
});
备注:
关于 dataType:如果这里定义的 dataType 与服务器返回的数据格式不一致,代码可能会执行失败,且很难查出原因,因为 HTTP 返回的状态码并未显示错误。因此在执行 Ajax 请求时,务必确保服务器返回的数据格式与事先定义的一致。通常情况下验证 HTTP 头信息中的 Content-type 是行之有效的办法,对于 JSON 而言,对应的 Content-type 应该是 application/json。
$.ajax 的一些自定义选项
$.ajax 方法的自定义选项非常多,这也是此方法功能强大的原因所在。若要查阅所有自定义选项,可参考官方文档:http://api.jquery.com/jQuery.ajax/,下面只列出一些常用的选项:
async:默认值是 true,如果需要 Ajax 的执行方式为同步,可将其设为 false。请注意,如果把这个值设为 false 了,那么你的其它 JavaScript 代码将会被中断执行,直到此次 Ajax 请求完毕,接受到服务端返回的数据为止才会恢复。所以,请慎用此选项。 cache:设定是否缓存服务端发回的数据。对于 “script” 和 “jsonp” 之外的其它格式的数据而言,默认值是 true。如果被设置为 false,向服务器发送请求的时候,URL 中会被加入一个查询字符串,字符串的值是当前的时间戳,以确保每次请求的 URL 都是不同的,当然也就不存在缓存问题了。JavaScript 中获取时间戳的方法为 new Date().getTime()。 complete:Ajax 请求执行完成时触发的回调函数,无论此次执行成功与否,该回调函数都会被触发。该回调函数可以接受服务端返回的原始信息及状态码。 context:定义回调函数执行时的作用域(回调函数 function(s) {alert(this)} 中的 this 指向谁?)。默认情况下,回调函数中的 this 指向传递给 $.ajax 方法的参数,也就是那个大对象。 data:要发送给服务端的数据,其值可以是一个对象或者查询字符串,如 foo=bar&baz=bim。 dataType:服务端返回数据的类型。如果不设置这个选项,jQuery 会根据服务端返回数据的 MIME 类型自行判断。 error:当 Ajax 执行错误时将会触发的回调函数,该函数接受原始的请求信息及状态码。 jsonp:执行 JSONP 请求时需要制定的回调函数名称,默认值是“callback”。 success:Ajax 成功执行时将会触发的回调函数。在函数中可获取服务端返回的信息(如果 dataType 被设置成 JSON,返回的数据应该是一个 JavaScript 对象),当然也可获取服务端返回的原始数据信息及状态码。 timeout:给 Ajax 请求设置一个超时是时间,单位是毫秒。 type:指定请求的方式,GET 或者 POST,默认值是 GET。其它如 PUT 和 DELETE 方式也可以用,但并不是所有浏览器都支持。 url:要请求的 URL。
其中 url 选项是所有选项中唯一的一个必选项,其它选项都是可选的。 一些简便方法
jQuery 简便 Ajax 方法
如果你不需要那么多可配置的选项,也不关心 Ajax 执行错误时候的相关处理,jQuery 同样提供了一些非常有用的简便方法,以更简洁的方式完成 Ajax 请求。其实这些简便写法只是封装了 $.ajax,并把某些选项预先设定好。
jQuery 提供的简便方法如下:
- $.get:对给定的 URL 执行 GET 请求。
- $.post:对给定的 URL 执行 POST 请求。
- $.getScript:向页面中添加脚本。
- $.getJSON:执行一个 GET 请求,服务端返回的信息应为 JSON。
以上每种简便方法中都可传递如下参数:
url:所请求的 URL,必须提供。 data:向服务端发送的数据,可选。可以是一个对象,亦或查询字符串,如 foo=bar&baz=bim。
- 备注:此选项不适用于 $.getScript。
一个回调函数:此回调函数在请求成功执行后被触发。可选。该回调函数接受服务端返回的数据,也包括请求的状态码及原始对象。 数据类型:服务端返回数据的类型。可选。
- 备注:此选项只适用于那些在其名称中没指定数据类型的方法。
下面是三个简便方法的示例:
// 获取纯文本或者 html
$.get('/users.php', { userId : 1234 }, function(resp) {
console.log(resp);
});
// 向页面中添加脚本,然后执行脚本中定义的函数。
$.getScript('/static/js/myScript.js', function() {
functionFromMyScript();
});
// 从服务端获取 JSON 格式的数据。
$.getJSON('/details.php', function(resp) {
$.each(resp, function(k, v) {
console.log(k + ' : ' + v);
});
});
$.fn.load 方法应用
$.fn.load
$.fn.load 方法是 jQuery 所有 Ajax 方法中唯一在选择器结果集上调用的方法。$.fn.load 方法从给定的 URL 上获取信息,然后填充到选择器结果集包含的元素中。另外,在 URL 后面还可以附加一些选择器,jQuery 最终只会把跟选择器相匹配的内容填充到对应的 HTML 元素中。
下面是示例:
$('#newContent').load('/foo.html');
// 或
$('#newContent').load('/foo.html #myDiv h1:first', function(html) {
alert('加载完毕!');
});
表单序列化与处理
Ajax 和 表单
在跟表单打交道方面,jQuery 的 Ajax 更显神威。最为有用的两个方法就是 $.fn.serialize 和 $.fn.serializeArray,下面是它们的用法:
// 将表单中数据转化为查询字符串
$('#myForm').serialize();
$('#myForm').serializeArray();
// 将表单中数据转化为对象数组,如:
[
{ name : 'field1', value : 123 },
{ name : 'field2', value : 'hello world' }
]
JSONP 跨域实战示例
使用 JSONP
JSON 的本质其实是一种跨站点脚本注入。现在有很多比较好的网站都提供了 JSONP 服务,允许我们用他们预先定义好的 API 获取他们的数据。下面是一个示例,来源于 http://www.giantflyingsaucer.com/blog/?p=2682
服务端代码:
<?php
header("content-type: text/javascript");
if(isset($_GET['name']) && isset($_GET['callback'])) {
$obj->name = $_GET['name'];
$obj->message = "Hello " . $obj->name;
echo $_GET['callback']. '(' . json_encode($obj) . ');';
}
?>
客户端代码:
$.ajax({
url: 'http://otherDomail.com:8080/JSONP/jsonp-demo.php',
data: {name: 'Super man'},
dataType: 'jsonp',
jsonp: 'callback',
success: function( response ) {
console.log( response.message );
}
});
jQuery 把 JSONP 的实现细节隐藏在幕后,我们要做的就是告诉 jQuery 服务端定义好的函数名以及我们请求的数据类型是 JSONP,其它方面和普通的 Ajax 请求没什么区别。 Ajax 事件
Ajax 事件绑定
很多时候我们都需要在 Ajax 请求开始或结束时做一些操作,例如显示或隐藏一个 loading… 图片。这些工作本可以在每个 Ajax 请求中各自实现,但是 jQuery 提供了更好的方法,你可以像绑定普通事件一样绑定 Ajax 事件。若要参阅全部事件列表,可访问 http://docs.jquery.com/Ajax_Events。下面是简单示例:
$('#loading_indicator')
.ajaxStart(function() { $(this).show(); })
.ajaxStop(function() { $(this).hide(); });
JavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
