详解JavaScript中jQuery和Ajax以及JSONP的联合使用

借助于 XMLHttpRequest,浏览器可以在整个页面不刷新的情况下与服务端进行交互,这就是所谓的 Ajax(Asynchronous JavaScript and XML)。Ajax 可以为用户提供更为丰富的用户体验。

Ajax 请求由 JavaScript 驱动,通过 JavaScript 代码向 URL 发送一个请求,待服务端有响应时会触发一个回调函数,可以在这里回调函数里面处理服务端返回的信息。由于整个发送请求和响应的过程是异步的,所以在此期间页面中其它 Javascript 代码仍然继续执行,不会中断。

jQuery 对 Ajax 当然也提供了很好的支持,而且还抽象了各种浏览器对于 Ajax 支持方面另人痛苦的差异。它不但提供了全功能的 $.ajax() 方法,还有诸如 $.get(),$.getScript(),$.getJSON(),$.post() 和 $().load() 等更为简便的方法。

尽管被命名为 Ajax,但是很多 Ajax 应用并没有使用 XML,特别是 jQuery 方面的 Ajax 应用,大多数都没有使用 XML;反而用得比较多的情况是:纯文本、HTML 以及 JSON(JavaScript Object Notation)。

一般情况下,由于同源策略(同协议,同域名,同端口)的限制,Ajax 并不能跨域执行请求,除非使用诸如 JSONP(JSON with Padding) 之类的方案,才能实现一些受限的跨域功能。
关于 Ajax 的一些重要概念

GET vs 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,前面已经说过,一般情况下 Ajax 的请求会被限制在相同协议(http 或 https)、相同端口、相同域名下才能正确执行,但是 HTML 的 <script> 标签却无此限制,它可以载入任何域下的脚本,jQuery 正是利用了这一点才得以拥有跨域执行 Ajax 的能力。

所谓 JSONP,就是其它域的服务端返回给我们的是 JavaScript 代码,这段代码可以被加载到 HTML 中的 <script> 标签中,这段 JavaScript 代码中包含有从其它域下的服务端返回的 JSON 数据,并以回调函数的形式提供。这样一来 jQuery 就回避了同源策略的限制,曲线拥有了跨域执行 Ajax 的能力。

Ajax 调试工具,现在比较新的浏览器如 Chrome 和 Safari,甚至 IE 都内置了调试工具,Firefox 也有无比强大 FireBug 插件,借助于这些调试工具,可以非常详细的查看 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 选项是所有选项中唯一的一个必选项,其它选项都是可选的。
一些简便方法

如果你不需要那么多可配置的选项,也不关心 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 方法是 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

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 请求开始或结束时做一些操作,例如显示或隐藏一个 loading… 图片。这些工作本可以在每个 Ajax 请求中各自实现,但是 jQuery 提供了更好的方法,你可以像绑定普通事件一样绑定 Ajax 事件。若要参阅全部事件列表,可访问 http://docs.jquery.com/Ajax_Events。下面是简单示例:

$('#loading_indicator')
  .ajaxStart(function() { $(this).show(); })
  .ajaxStop(function() { $(this).hide(); });
(0)

相关推荐

  • jQuery插件jQuery-JSONP开发ajax调用使用注意事项

    JSONP 调用示例代码: 复制代码 代码如下: var originImgSrc = 'cnbogs-logo.gif';$.jsonp({    url: '',    data: { imgSrc: originImgSrc },    callbackParameter: "callback",    success: function (newImgSrc, textStatus, xOptions) {        console.log(xOptions.data.im

  • 跨域请求之jQuery的ajax jsonp的使用解惑

    直接执行了error方法提示错误--ajax jsonp之前并没有用过,对其的理解为跟普通的ajax请求差不多,没有深入了解:出现了这种错误,几经调试(检查后台的代码和js部分的属性设置)还是不行,让我感觉很是意外和不解.于是,决定仔细研究下ajax jsonp的使用,并将最后测试成功的学习经验和大家分享下! 首先,贴出可以成功执行的代码: (页面部分) 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional

  • 全面解析Ajax和jsonp使用总结

    前言:ajax和jsonp可以与后台通信,获取数据和信息,但是又不用刷新整个页面,实现页面的局部刷新. 一.ajax •定义:一种发送http请求与后台进行异步通讯的技术. •原理:实例化xmlhttp对象,使用此对象与后台通信. ajax的同源策略: •ajax请求的页面或资源只能是同一个域下面的资源,不能是其他域的资源,这是在设计ajax时基于安全考虑. ---------------------------------------------------------------------

  • 浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用

    JSON和JSONP   JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,用于在浏览器和服务器之间交换信息.   JSONP(JSON With Padding),就是打包在函数调用中的的JSON(或者包裹的JSON).   JSON是一种数据格式,JSONP是一种数据调用方式. 复制代码 代码如下: //JSON  {  "name": "sb"  } 复制代码 代码如下: //JSONP  callback({  &q

  • jquery ajax中使用jsonp的限制解决方法

    jsonp 解决的是跨域 ajax 调用的问题.为什么要跨域 ajax 调用呢?这样可以在一个应用中直接在前端通过 js 调用另外一个应用(在不同的域名下)的 API.我们在实际应用中也用到了 jsonp ,但之前只知道 jsonp 的一个限制,只能发 get 请求,get 请求的弊端是请求长度有限制.今天,发现 jsonp 的另外一个限制(在jquery ajax的场景下) -- 不会触发 $.ajax 的error callback,示例代码如下: 复制代码 代码如下: $.ajax({  

  • 详解JavaScript中jQuery和Ajax以及JSONP的联合使用

    借助于 XMLHttpRequest,浏览器可以在整个页面不刷新的情况下与服务端进行交互,这就是所谓的 Ajax(Asynchronous JavaScript and XML).Ajax 可以为用户提供更为丰富的用户体验. Ajax 请求由 JavaScript 驱动,通过 JavaScript 代码向 URL 发送一个请求,待服务端有响应时会触发一个回调函数,可以在这里回调函数里面处理服务端返回的信息.由于整个发送请求和响应的过程是异步的,所以在此期间页面中其它 Javascript 代码仍

  • 详解JavaScript中的链式调用

    链模式 链模式是一种链式调用的方式,准确来说不属于通常定义的设计模式范畴,但链式调用是一种非常有用的代码构建技巧. 描述 链式调用在JavaScript语言中很常见,如jQuery.Promise等,都是使用的链式调用,当我们在调用同一对象多次其属性或方法的时候,我们需要多次书写对象进行.或()操作,链式调用是一种简化此过程的一种编码方式,使代码简洁.易读. 链式调用通常有以下几种实现方式,但是本质上相似,都是通过返回对象供之后进行调用. this的作用域链,jQuery的实现方式,通常链式调用

  • 详解JavaScript中的箭头函数的使用

    目录 前言 箭头函数语法 无圆括号语法 隐式返回 注意隐式返回错误 无法命名箭头函数 如何处理this关键字 匿名箭头函数 不正常工作的情况 箭头函数作为对象方法 箭头函数与第三方库 箭头函数没有arguments对象 总结 前言 本文可以让你了解所有有关JavaScript箭头函数的信息.我们将告诉你如何使用ES6的箭头语法,以及在代码中使用箭头函数时需要注意的一些常见错误.你会看到很多例子来说明它们是如何工作的. JavaScript的箭头函数随着ECMAScript 2015的发布而到来,

  • 详解JavaScript中的4种类型识别方法

    具体内容如下: 1.typeof [输出]首字母小写的字符串形式 [功能] [a]可以识别标准类型(将Null识别为object) [b]不能识别具体的对象类型(Function除外) [实例] console.log(typeof "jerry");//"string" console.log(typeof 12);//"number" console.log(typeof true);//"boolean" console

  • 详解JavaScript 中getElementsByName在IE中的注意事项

    详解JavaScript 中getElementsByName在IE中的注意事项 前言: 在IE5-9中是没有实现js的 getElementsByClassName()方法,但是实现了getElementsByName()方法,但是需要注意的是这个方法在IE5-9中也返回id属性匹配的指定元素,为了兼容,应该小心谨慎使用,不要将同样的字符串同时用作了名字和ID. 测试程序如下: <div id="log"> <div id="innerLog"&

  • 详解Javascript中prototype属性(推荐)

    在典型的面向对象的语言中,如java,都存在类(class)的概念,类就是对象的模板,对象就是类的实例.但是在Javascript语言体系中,是不存在类(Class)的概念的,javascript中不是基于'类的',而是通过构造函数(constructor)和原型链(prototype chains)实现的.但是在ES6中提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板.通过class关键字,可以定义类.基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能

  • 详解Javascript 中的 class、构造函数、工厂函数

    到了ES6时代,我们创建对象的手段又增加了,在不同的场景下我们可以选择不同的方法来建立.现在就主要有三种方法来构建对象,class关键字,构造函数,工厂函数.他们都是创建对象的手段,但是却又有不同的地方,平时开发时,也需要针对这不同来选择. 首先我们来看一下,这三种方法是怎样的 // class 关键字,ES6新特性 class ClassCar { drive () { console.log('Vroom!'); } } const car1 = new ClassCar(); consol

  • 详解JavaScript中的Object.is()与"==="运算符总结

    三重相等运算符 === 严格检查2个值是否相同: 1 === 1; // => true 1 === '1'; // => false 1 === true; // => false 但是,ES2015规范引入了 Object.is(),其行为与严格的相等运算符几乎相同: Object.is(1, 1); // => true Object.is(1, '1'); // => false Object.is(1, true); // => false 主要问题是:什么时

  • 详解JavaScript中的this指向问题

    题记 JS中的this指向一直是个让初学者头疼的问题.今天,我们就一起来瞅瞅this倒地是咋回事,详细说说this指向原则,从此不再为了this指向操碎了心. 开篇 首先我们都知道this是Javascript语言的一个关键字. 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.随着函数使用场合的不同,this的值会发生变化.但是有一个总的原则,那就是this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它所在函

  • 详解JavaScript中new操作符的解析和实现

    前言 new 运算符是我们在用构造函数创建实例的时候使用的,本文来说一下 new 运算符的执行过程和如何自己实现一个类似 new 运算符的函数. new 运算符的运行过程 new 运算符的主要目的就是为我们创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例(比如箭头函数就没有构造函数,所以是不能 new 的).new 操作符的执行大概有以下几个步骤: 创建一个新的空对象 把新对象的 __proto__ 链接到构造函数的 prototype 对象(每一个用户定义函数都有一个 proto

随机推荐