jQuery - Ajax

传统的网页需要通过重新加载来更新它的内容。此种方式非常的低效,服务器不得不重构整个页面,之后再发送所有的 HTML CSS JavaScript 到用户端。2003年之后,大部分主流浏览器,通过 XMLHttpRequest(XHR) 对象来解决这个问题,允许浏览器同服务器进行通信,而无需重新加载页面。

XMLHttpRequest 对象是 Ajax(Asynchronous JavaScript and XML) 技术的一部分。Ajax 请求由 JavaScript 触发,发送请求至某个 URL,当接收到响应时,一个回调函数会被触发来处理此响应。由于请求是异步的,所以余下的代码可以继续执行。

不幸的是,不同的浏览器通过不同的方式执行 Ajax API。幸运的是 jQuery 提供 Ajax 支持,来消除各个浏览器之间的差异;它提供全功能的 $.ajax() 方法,和其他简单便捷的方法,例如:$.get() $.getScript() $.getJSON() $.post() $().load()

大多数 jQuery 应用程式不使用 XML 来传递数据,而是通过原始的 HTML 或者 JSON(JavaScript Object Notation) 来传递数据。

一般来说,Ajax 不能跨网域工作。example1.com 不能发送 Ajax 请求至 example2.com。解决方案:JSONP (JSON with Padding) 使用 <script> 标签,从另一个域加载包含任一 JavaScript 内容和 JSON 的文件。更多的浏览器已经使用一种称为 Cross-Origin Resource Sharing (CORS) 的技术,来允许 Ajax 请求不同的网域。


Key Concepts 关键概念

GET vs POST

用于向服务器发送请求的最常见的两种方法是:GET 和 POST。

GET 方法应当用于非破坏性的操作。指该操作仅仅从服务端获取数据,不改变服务端的数据。浏览器可能会缓存 GET 请求。GET 请求通常在查询字符串中发送它所有的数据。

POST 方法用于破坏性的操作。指该操作会改变服务端的数据。POST 通常不会被浏览器缓存;查询字符串可以作为 URL 的一部分,但是数据往往作为发布数据单独发送。

Data Types

jQuery 需要一些指令来设置,需要从 Ajax 请求中取得的数据的数据类型。

text 用于传输简单字符串。

html 用于传输要放置在页面上的 HTML 块。

script 用于向页面添加新脚本。

json 用于传输 JSON 格式的数据;其中可以包含字符串、数组、对象。

jsonp 用于从另一个网域传输 JSON 数据。

xml 用于传输在自定义 XML 架构中的数据。

Asynchronous 异步性

由于请求是异步的,所以请求的响应只能通过回调函数处理。示例:

var response;
 
$.get( "foo.php", function( r ) {
    response = r;
});
console.log( response ); // undefined


$.get( "foo.php", function( response ) {
    console.log( response ); // server response
});

Same-Origin Policy(同源政策) and JSONP

通常,Ajax 请求仅限于与发出请求的页面相同的协议(http 或 https);相同的端口和相同的网域。此限制不适用于通过 jQuery 的 Ajax 方法加载的脚本。注意:IE10以下版本的浏览器不支持 cross-domain AJAX 请求。

另一个例外是针对另一个网域上的 JSONP 服务的请求。在 JSONP 的情况下,服务提供者同意使用脚本来响应请求,该脚本使用 <script> 标签来载入请求页面,以此方式来避免同源的限制;该脚本将包含请求的数据。


jQuery's Ajax-Related Methods

$.ajax()

提供 configuration 对象包含完成请求所需的所有操作指南;提供请求成功或失败之后的回调函数。完整文档:jQuery.ajax

// Using the core $.ajax() method
$.ajax({
 
    // The URL for the request
    url: "post.php",
 
    // The data to send (will be converted to a query string)
    data: {
        id: 123
    },
 
    // Whether this is a POST or GET request
    type: "GET",
 
    // The type of data we expect back
    dataType : "json",
})
  // Code to run if the request succeeds (is done);
  // The response is passed to the function
  .done(function( json ) {
     $( "<h1>" ).text( json.title ).appendTo( "body" );
     $( "<div class=\"content\">").html( json.html ).appendTo( "body" );
  })
  // Code to run if the request fails; the raw request and
  // status codes are passed to the function
  .fail(function( xhr, status, errorThrown ) {
    alert( "Sorry, there was a problem!" );
    console.log( "Error: " + errorThrown );
    console.log( "Status: " + status );
    console.dir( xhr );
  })
  // Code to run regardless of success or failure;
  .always(function( xhr, status ) {
    alert( "The request is complete!" );
  });

注意:dataType 的设置,若该设置同服务端返回的数据类型不同,请求会失败。

$.ajax Options

async 默认值为:true。若设置为:false 表示该请求为同步请求,若设置为同步请求,该请求会阻塞后续代码的执行,直到该请求接收到响应。

cache 是否使用缓存响应(若可用)。默认值为:true;除了 dataType 为:script jsonp。若设置为:false,URL 会附加一个 cachebusting 参数。

done 请求成功的回调函数。该回调函数会接收响应的数据,以及请求的文本状态和未加工的请求对象。

fail 请求结果出错后调用的回调函数。该函数会接收请求的未加工的请求对象和请求的文本状态。

always 请求执行完成之后调用的回调函数,无论请求成功或失败。该函数会接收请求的未加工的请求对象和请求的文本状态。

context 回调函数执行的范围。默认情况下,回调函数中的 this 指向起初传入 $.ajax() 中的对象。

data 发送至服务端的数据。可以是对象或查询字符创(foo=bar&amp;baz=bin)。

dataType 期望服务端返回的数据类型。若未指定,默认类型为 MIME 类型。

jsonp 要发送 jsonp 请求时,要在查询字符串中发送的回调函数名称。

timeout 设定请求等待的超时时间,单位:毫秒。

traditional 设置为:true 以使用 jQuery 1.4 版本之前的参数序列化样式。完整文档:jQuery.param

type 请求的类型:GET 或 POST;默认为:GET。其他类型如:PUT DELETE,但是可能不是所有的浏览器都支持。

url 请求的 URL。

url 属性是 $.ajax() 方法的 configuration 对象所必须的属性,其他都是可选属性。

Convenience Methods 便捷方法

$.get 发送 GET 请求至提供的 URL。

$.post 发送 POST 请求至提供的 URL。

$.getScript 在页面加入脚本。

$.getJSON 发送 GET 请求,并期望服务端返回 JSON 格式数据。

以上便捷方法,都采用一下参数:

url 请求的 URL;必须参数。

data 发送至服务端的数据;可选参数。可以为对象或查询字符创。注意:该参数对 $.getScript 不是有效的。

success callback 请求成功之后调用的回调函数;可选参数。回调函数接收响应的数据(若数据类型为:JSON,会将其转换为:JavaScript 对象),以及请求的文本状态和未加工的请求对象。

data type 期望服务端返回的数据类型;可选参数。

// Using jQuery's Ajax convenience methods
 
// Get plain text or HTML
$.get( "/users.php", {
    userId: 1234
}, function( resp ) {
    console.log( resp ); // server response
});
 
// Add a script to the page, then run a function defined in it
$.getScript( "/static/js/myScript.js", function() {
    functionFromMyScript();
});
 
// Get JSON-formatted data from the server
$.getJSON( "/details.php", function( resp ) {
 
    // Log each key in the response data
    $.each( resp, function( key, value ) {
        console.log( key + " : " + value );
    });
});

$.fn.load

.load() 方法在 jQuery's Ajax 中是惟一的,因为它在选择项中被调用。.load() 方法从指定 URL 取得 HTML,之后使用返回的 HTML 来构成选择项元素。

// Using .load() to populate an element
$( "#newContent" ).load( "/foo.html" );


// Using .load() to populate an element based on a selector
$( "#newContent" ).load( "/foo.html #myDiv h1:first", function( html ) {
    alert( "Content updated!" );
});

Ajax and Forms

Serialization

使用 .serialize() 和 .serializeArray() 来序列化表单的输入。

.serialize() 方法将表单数据序列化入查询字符串。为了使元素值可以被序列化,该元素必须有 name 属性。checkbox radio 类型的输入框,只有在被选中时,才会被包含入序列化中。

// Turning form data into a query string
$( "#myForm" ).serialize();
 
// Creates a query string like this:
// field_1=something&field2=somethingElse

然而简单原始的序列非常巨大,使用对象型的数组,代替查询字符串,会比较优秀。此时使用 .serializeArray() 方法,该方法产生对象型的数组,来代替字符创。

// Creating an array of objects containing form data
$( "#myForm" ).serializeArray();
 
// Creates a structure like this:
// [
//   {
//     name : "field_1",
//     value : "something"
//   },
//   {
//     name : "field_2",
//     value : "somethingElse"
//   }
// ]

Clident-side Validation

// Using validation to check for the presence of an input
$( "#form" ).submit(function( event ) {
 
    // If .required's value's length is zero
    if ( $( ".required" ).val().length === 0 ) {
 
        // Usually show some kind of error message here
 
        // Prevent the form from submitting
        event.preventDefault();
    } else {
 
        // Run $.ajax() here
    }
});


// Validate a phone number field
$( "#form" ).submit(function( event ) {
    var inputtedPhoneNumber = $( "#phone" ).val();
 
    // Match only numbers
    var phoneNumberRegex = /^\d*$/;
 
    // If the phone number doesn't match the regex
    if ( !phoneNumberRegex.test( inputtedPhoneNumber ) ) {
 
        // Usually show some kind of error message here
 
        // Prevent the form from submitting
        event.preventDefault();
    } else {
 
        // Run $.ajax() here
    }
});

Prefiltering

预过滤器是一种在发送请求前改变 ajax 请求选项的方式。

// Using a proxy with a prefilter
$.ajaxPrefilter(function( options, originalOptions, jqXHR ) {
    if ( options.crossDomain ) {
        options.url = "http://mydomain.net/proxy/" + encodeURIComponent( options.url );
        options.crossDomain = false;
    }
});

可以在回调函数之前传入参数,以指定那种数据类型应用预过滤器。

// Using the optional dataTypes argument
$.ajaxPrefilter( "json script", function( options, originalOptions, jqXHR ) {
 
    // Do all of the prefiltering here, but only for
    // requests that indicate a dataType of "JSON" or "script"
});

Working with JSONP

JSONP 本质上是一个双方同意的跨站脚本攻击。例如:Yahoo APIs

// Using YQL and JSONP
$.ajax({
    url: "http://query.yahooapis.com/v1/public/yql",
 
    // The name of the callback parameter, as specified by the YQL service
    jsonp: "callback",
 
    // Tell jQuery we're expecting JSONP
    dataType: "jsonp",
 
    // Tell YQL what we want and that we want JSON
    data: {
        q: "select title,abstract,url from search.news where query=\"cat\"",
        format: "json"
    },
 
    // Work with the response
    success: function( response ) {
        console.log( response ); // server response
    }
});

Ajax Events

有时在在 Ajax 请求开始或停止时,会执行某些操作;例如:显示或者隐藏加载指示器。可以将 Ajax 事件绑定在元素上,而不是在每个 Ajax 请求中定义这些行为。完整文档:Ajax Events

// Setting up a loading indicator using Ajax Events
$( "#loading_indicator" )
    .ajaxStart(function() {
        $( this ).show();
    })
    .ajaxStop(function() {
        $( this ).hide();
    });

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值