jQuery Ajax

我們這裡談 jQuery 中 Ajax 的操作是如何應用,若不是太了解 Ajax 的朋友可以先看看維基百科上的說明

jQuery 將 (最底層的) jQuery.ajax() 包裝成下面幾個常用的簡單函式來作 Ajax Request;但是如果你有更複雜的使用需求,還是要用到稍後會提到的 jQuery.ajax()

.load(url [, data] [, complete])

load 函式用來動態載入 HTML 文件並把它插入 DOM 中。此函式預設是以 GET 的方式來發送請求,但是如果有設參數 data 則會自動轉為 POST。

參數型別說明
urlString指定要進行呼叫的位址
dataMap要傳給server的Key/value值對
completeFunctionAjax 請求完成時 (不需要是 success) 呼叫的 callback

例如,載入 ajax/test.html 網頁的內容放到 #result 中:

$('#result').load('ajax/test.html');

也可以多一個 callback:

$('#result').load('ajax/test.html', function(responseText, textStatus, jqXHR) {
  // this - 指向 #result DOM 元素
  // responseText - 請求的文件內容
  // textStatus - 請求狀態 (success, error)
  // jqXHR - XMLHttpRequest Object
});

對於 url 參數我們還可以加上 selector 來篩選被載入的 HTML,即將 URL 參數的型式寫如 url selector

例如,將 ajax/test.html 網頁裡面的 #container 元素內容,載入到 #result 中:

$('#result').load('ajax/test.html #container');

jQuery.get(url [, data] [, success] [, dataType])

$.get() 一個簡單的 HTTP GET 不同步請求,如果你想在出錯時 (error) 能執行一些函式,那你得使用 $.ajax()。

參數型別說明
urlString指定要進行呼叫的位址
dataObject要傳給 server 的 Key/value 值對
successFunctionAjax 請求完成時 (必需是 success) 呼叫的 callback
dataTypeString返回的資料類型 - xml, html, script, json, jsonp, text。不設定的話 jQuery 會幫你猜返回的內容格式是什麼。

例如,取得 ajax/test.html 的內容,如果返回的內容是 JSON,jQuery 會自動幫你解析成一個 JavaScript object:

$.get('ajax/test.html', function(data) {
  $('.result').html(data.title);
});

也可以設定 url 的 GET 參數:

// 發出 HTTP 請求 test.php?name=John&time=2pm
$.get('test.php', {name: "John", time: "2pm"});

jQuery.post(url [, data] [, success] [, dataType])

$.post() 一個簡單的 HTTP POST 不同步請求函式,若想在出錯時 (error) 能執行一些函式,那你得使用 $.ajax。

$.post() 的使用方法跟 jQuery.get() 一樣。

jQuery.getScript(url [, success])

透用 HTTP GET 載入 JavaScript 檔案,並自動執行內容。

用法例如:

var url = 'https://code.jquery.com/color/jquery.color.js';
$.getScript( url, function() {
  // 等 script 載入後做些事...
});

也可以用 JSONP 的方式進行跨網域 (cross-domain) 請求,你需要在 URL 加上 "url?callback=?" (你也可以換個名稱不叫做 callback),當送出請求時,回呼函式名稱 "問號?" 會被 jQuery 自動取代為一個亂數的函數名稱 (如 callback=jsonp1225116612487),在 server 這邊你就可以抓 callback 的值來送回對應的 JSON 給 browser 來執行。

例如從 flickr API JSONP 抓取資料:

var flickerAPI = 'http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?';
$.getJSON(flickerAPI, {
  tags: 'mount rainier',
  tagmode: 'any',
  format: 'json'
}, function(data) {
  console.log(data);
})

jQuery Ajax 事件 (Events)

你可以設定在 Ajax 請求過程中觸發 jQuery 自定義的一些不同的事件,共分為兩大類 - "全域事件" 與 "局部事件"。

局部事件 (Local Events)

局部事件就是在 $.ajax() 物件 (稍後談到) 裡面定義到的事件,如:

$.ajax({
  beforeSend: function(){
    // beforeSend 事件發生時的處理函式
  },
  complete: function(){
    // complete 事件發生時的處理函式
  }
  // ...
});

全域事件 (Global Events)

全域事件是你可以在任何元素上綁定 Ajax Global Events,而當每次有 Ajax 請求時 jQuery 就會去適時地去觸發這些事件,如:

$('#loading').bind('ajaxSend', function() {
  $(this).show();
}).bind('ajaxComplete', function() {
  $(this).hide();
});

所有的 Global jQuery Ajax 事件列表

ajaxStart (Global Event)
一個 Ajax 請求產生且沒其它請求正在運行時

beforeSend (Local Event)
Ajax 請求發出之前

ajaxSend (Global Event)
同上

success (Local Event)
Ajax 請求成功時 (沒任何 error)

ajaxSuccess (Global Event)
同上

error (Local Event)
Ajax 請求發生錯誤時 (Ajax 請求不是 success,就是 error,沒都有的情況)

ajaxError (Global Event)
同上

complete (Local Event)
不論 Ajax 請求是 success 或是 error,都會觸發 complete 事件

ajaxComplete (Global Event)
同上

ajaxStop (Global Event)
沒有任何的 Ajax 請求正在運行時

事件觸發的順序:ajaxStart » ajaxSend » ajaxSuccess or ajaxError » ajaxComplete » ajaxStop

jQuery.ajax(url [, settings])

這是 jQuery 最底層的 Ajax 物件,而上面提到的都是由 $.ajax() 包成的簡單應用 ($.get, $.post 等)。$.ajax() 只有一個參數,一個包含初始化及處理 Ajax request 的 key/value pairs 物件,詳細參數選項 settings 如下所列:

參數名稱型別預設值說明
asyncBooleantrue是否同部請求
beforeSendFunction-發送請求之前可在此修改 XMLHttpRequest 物件,如添加 header 等,你可以在此函式中 return flase 取消 Ajax request
cacheBooleantrue / false (如果 dataType 是 script 或 jsonp)設定成 false 就不會從瀏覽器中抓 cache 住的舊資料
completeFunction-請求完成時執行的函式 (不論結果是 success 或 error)
contentTypeStringapplication/x-www-form-urlencoded傳送資料至 Server 的編碼類型
dataObject, String, Array-傳送至 Server 的資料,會自動轉為 query string 的型式,如果是 GET 請求還會幫你附加到 URL。可用 processData 選項禁止此自動轉換。物件型式則為 Key/Value pairs
dataFilterFunction-過濾 Server 回傳的資料。函式中第一個參數為資料,第二個則為 dataType。
function (data, type) {...}
dataTypeString自動判斷 (xml or html)預期 Server 傳回的資料類型,如果沒指定,jQuery 會根據 HTTP MIME Type 自動選擇以 responseXML 或 responseText 傳入你的 success callback。可選的資料類型有:
xml: 傳回可用 jQuery 處理的 XML
html: 傳回 HTML,包含 jQuery 會自動幫你處理的 script tags
script: 傳回可執行的 JavaScript。(script 不會被自動 cache,除非 cache 設為true
json: 傳回 JSON
jsonp: 在 URL 加上 callback=? 參數,並在 Server 端配合送回此 jsonp callback
text:傳回純文字字串
errorFunction-請求發生錯誤時執行函式
globalBooleantrue設定是否觸發全域 Ajax 事件
ifModifiedBooleanfalse由 Last-Modified header 判斷,僅在 Server 更新文件時才下載
processDataBooleantrue設定是否自動將 data 轉為 query string
successFunction-請求成功時執行函式
urlString目前 URL指定要進行呼叫的位址
typeStringGET請求方式 POST/GET

若有指定 dataType 選項,你要確定 Server 會傳回正確的 MIME 資訊 (如 xml 文件為 text/xml),錯誤的 MIME 訊息將會導致不可預期的錯誤!

若指定 dataType 選項為 script,所有跨網域的 POST 請求都會被轉成 GET,因為 jQuery 是利用 script tag 來下載。

用法例如,下載並執行 JavaScript 文件:

$.ajax({
  type: 'GET',
  url: 'test.js',
  dataType: 'script'
});

例如,儲存資料到 Server,並通知使用者已儲存:

$.ajax({
  type: 'POST',
  url: 'some.php',
  data: {name: 'John', location: 'Boston'},
  success: function(msg) {
    alert('Data Saved: ' + msg);
  }
});

其它函式 (Helper Functions)

.serialize()

序列化表單元素 (form elements) 內容為 "name1=value1&name2=value3···" 格式的字串 (string)。

$('form').on('submit', function(event) {
  event.preventDefault();
  console.log( $(this).serialize() );
});

.serializeArray()

序列化表單元素內容為 [{name: name, value: value}] 格式的陣列 (array)。

$('form').on('submit', function(event) {
  event.preventDefault();
  console.log( $(this).serializeArray() );
});

console.log 出來的結果會是個 array 內容像是:

[
  {
    name: "a",
    value: "1"
  },
  {
    name: "b",
    value: "2"
  },
  {
    name: "c",
    value: "3"
  },
  {
    name: "d",
    value: "4"
  },
  {
    name: "e",
    value: "5"
  }
]

jqXHR

在 jQuery 1.5 版後,所有 jQuery 的 Ajax 方法 ($.get, $.post, $.ajax, ...) 都會返回一個 jqXHR object,jqXHR 是 XMLHTTPRequest 的超集 (superset),同時實作了 Promise 的介面 (interface),讓我們可以更方便操作非同步的 Ajax 請求。

jqXHR object 有下面這些方法可以用,而這些方法本身都會 return jqXHR 讓你可以方便串接 (chaining):

jqXHR.done(function(data, textStatus, jqXHR) {})

Ajax call 成功完成時會執行 .done() callback

jqXHR.fail(function(jqXHR, textStatus, errorThrown) {})

Ajax call 失敗時會執行 .fal() callback

jqXHR.always(function(data|jqXHR, textStatus, jqXHR|errorThrown) {})

Ajax call 不管成功或失敗,都會執行 .always() callback

jqXHR.then(function(data, textStatus, jqXHR) {}, function(jqXHR, textStatus, errorThrown) {})

Ajax call 成功時,會執行第一個參數 callback;失敗時,會執行第二個參數 callback。


使用方法例子:

// Ajax call 可以串接多個處理函式
// 並把函式返回的 jqXHR 存回 jqxhr 變數
var jqxhr = $.ajax('example.php')
  .done(function() {
    alert('成功');
  })
  .fail(function() {
    alert('失敗');
  })
  .always(function() {
    alert('結束');
  });
 
// .....
 
// .done() .fail() .always() .then() 都可以重複 call 很多次
// 所有 callback 都會依序的執行
jqxhr.always(function() {
  alert('結束 part 2');
});