AJAX JavaScript 與 jQuery 教學範例 for PHP

使用 JavaScript 與 jQuery 兩種方式搭配 PHP,來各別實作 AJAX 應用,並解說 AJAX 的原理,與 HTTP request、response 的 headers、body 內容解說,以及實現 AJAX 的 XMLHttpRequest 物件。
簡介
什麼是 AJAX
AJAX(Asynchronous JavaScript and XML,非同步的 JavaScript 與 XML 技術)並不是一種程式語言,而是一種不需重新載入整個網頁的情況下,能夠更新部分網頁,綜合了「伺服」(如 PHP)與「客戶」(JavaScript)語言的瀏覽器端網頁開發技術。
表單(form)vs AJAX
表單 – 發送 HTTP 請求
早期傳統的 Web 應用,通常都是使用表單(form)向伺服器發送一個 HTTP 請求,伺服器接收處理傳來的表單並送回一個新的網頁,但前後兩個頁面的大部份 HTML 碼通常僅有約 5% 是變動的資料,這種做法浪費了許多頻寬。
AJAX – 發送 HTTP 請求
AJAX 應用可以僅向伺服器傳送並取回指定資料,接著在客戶端使用 JavaScript 處理伺服器回應的資料,因只取須要的資料,所以伺服器回應更快且負荷也減少了。
AJAX 運作原理
- 使用者在「瀏覽器」觸發一個事件,例如點擊按鈕
- 將上述獲的事件的同時,使用 JavaScript 的
XMLHttpRequest
物件,在背景對「Web 伺服器」發送一個 HTTP 請求,達到與「Web 伺服器」進行資料的非同步交換 - 將從「Web 伺服器」取得的資料,使用 JavaScript 操作 DOM,來實現動態局部更新「瀏覽器」的網頁內容
HTTP
完整的 HTTP 流程
一個完整的 HTTP 流程,通常有下面七個步驟:
- 建立 TCP 連接
- 瀏覽器:向「Web 伺服器」發送請求命令
- 瀏覽器:發送請求表頭(headers)
- Web 伺服器:回應(response)
- Web 伺服器:發送回應(response)資訊
- Web 伺服器:向「瀏覽器」發送資料
- Web 伺服器:關閉 TCP 連接
HTTP 請求方法(GET 與 POST)
GET
- 適用於資訊獲取(查詢結果)
- 使用 URL 傳遞參數(name=value)
- 對所發送資訊的數量有限制,一般在 2,000 個字串
POST
- 適用於修改伺服器上的資料
- 所有傳遞的參數(name=value)將被嵌入 HTTP 的請求主體(body)
- 對所發送資訊的數量無限制
HTTP 請求(request)
一個 HTTP 請求由四個部分構成:
- HTTP 請求方法(method)或「動詞」(verb),比如是 GET 或 POST 請求
- 要請求的 URL,就是請求的網址
- 一組選擇性的請求表頭(headers),包含一些「客戶端環境」與「身份驗證」資訊...
- 一個選擇性的請求主體(body),也就是請求正文,可包含客戶提交的「查詢字串」或「表單」資訊...
HTTP 請求內容
- 請求方法:GET
- 請求地址:/service.php?number=1020501
- HTTP 版本:HTTP/1.1
- 請求表頭:紅框部分
- 請求主體:綠框部分
GET /service.php?number=1020501 HTTP/1.1Host: localhost Connection: keep-alive User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.99 Safari/537.36 q=0.01 Accept: */* Referer: http://localhost/javascript-demo.html Accept-Encoding: gzip, deflate, sdch Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4number=1020501
HTTP 回應(response)
伺服器的 HTTP 回應(response)有三個部分:
- 由數值與文字所組成的狀態碼(status code),指示請求成功或失敗
- 一組回應表頭(headers)包含許多有用的資訊,例如伺服器類型、日期時間、內容類型和長度...
- 回應主體(body)也就是回應正文,例如「文字字串」或「HTML 代碼」...
HTTP 回應內容
- HTTP 版本:HTTP/1.1
- 回應狀態碼:200 OK,代表請求成功
- 回應資料類型:application/json; charset=UTF-8,代表資料類型 JSON;編碼格式 UTF-8
- 回應表頭:紅框部分
- 回應主體:綠框部分(這裡回應的資料格式為 JSON)
HTTP/1.1 200 OKDate: Sat, 26 Sep 2015 06:12:28 GMT Server: Apache/2.4.12 (Win32) OpenSSL/1.0.1l PHP/5.6.8 X-Powered-By: PHP/5.6.8 Content-Length: 111 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: application/json; charset=UTF-8{"number":"1020501","name":"\u738b\u4e00\u5091","sex":"\u7537"}
HTTP 狀態碼(status code)
HTTP 狀態碼由 3 位數字組成,第一個位數定義了回應的物件(後兩位數沒有代表任何具體的分類)。
- 1xx:指示資訊。表示收到 Web 瀏覽器請求,正在進一步的處理中
- 2xx:成功。表示請求已經被正確接收,並已經被理解和接受,例如:200 OK
- 3xx:重新導向。表示請求沒有成功,必須採取進一步的動作以完成請求
- 4xx:客戶端錯誤。表示客戶端提交的請求中有錯誤或者不能被完成,例如:404 NOT found,代表請求中引用的檔案不存在
- 5xx:伺服器錯誤。表示伺服器不能完成請求的處理,儘管請求是正確的,例如:500 Internal Server Error,代表伺服器遇到了一個未曾預料的狀況,通常是伺服器的程式碼出錯
XMLHttpRequest 物件(object)
瀏覽器將它們的 HTTP API 定義在一個 XMLHttpRequest
物件之上。此物件的每個實體皆代表一組 request / response 的配對,而這個物件的「屬性」與「方法」讓你能夠:
- 做出 POST、HEAD 及普通 GET 請求(request)的能力
- 同步(sync)或非同步(async)擷取 Web 伺服器的回應(response),並且能夠以「文字」或一個「DOM」檔案... 的形式返回內容
XMLHttpRequest
它並不限於只能用在 XML 檔案,它可以接收任何形式的文字檔案建構子(constructor)
XMLHttpRequest()
呼叫任何方法前一定要先呼叫建構子,例如:
瀏覽器支援
XMLHttpRequest
物件第一次的出現是在 Microsoft 的 IE5 中,但在 IE5 及 IE6 中它是以 ActiveX
物件的形式提供。現在標準的 XMLHttpRequest()
建構子在 IE7 之前並沒有支援(現代瀏覽器都有支援),但可這樣模擬它的功能,以相容所有瀏覽器(包含 IE7 之前):
屬性(attribute)
readyState
HTTP 請求的狀態,當一個 XMLHttpRequest
初次建立時,這個屬性的值為 0,直到接收到完整的 HTTP 回應(response),則值增加到 4。
值 | 狀態 | 描述 |
---|---|---|
0 | UNSENT | open() 尚未被呼叫 |
1 | OPEND | open() 方法已被呼叫,但 send() 方法未被呼叫 |
2 | HEADERS_RECEIVED | send() 方法已被呼叫,而且可取得 header 與狀態 |
3 | LOADING | 回應資料下載中,此時 responseText 會擁有部分資料 |
4 | DONE | 回應(response)已經完成 |
responseText
回應請求的字串資料;如果請求失敗或尚未完成,則為 null
。
responseXML
回應請求的 DOM 文件物件(Document Object),如果請求失敗、尚未完成或回傳資料無法解析為 XML 或 HTML 檔,則為 null
。回應會如同 text / html 一般一樣被解析。當 responseType
被設為 "document" 而且請求不是非同步,回應會如同 text / html 一般一樣被解析。
status
請求回應狀態,也就是 HTTP 狀態碼(status code),例如:200 代表成功;404 NOT Found,代表請求中引用的檔案不存在。
statusText
與 status
不一樣的是回應狀態字串(Status String),且會包含完整的回傳訊息,例如:"200 OK";"404 NOT Found"。
事件(event)
onreadystatechange
當 readyState
屬性每次改變時呼叫的 JavaScript 函式,是從使用者介面的執行緒中呼叫。
方法(method)
abort()
終止送出的請求。
這個方法會將 readyState
屬性重置為 0,回應不再必要的時候,可以呼叫這個方法。
getAllResponseHeaders()
以字串型態回傳所有回應表頭(response headers),如果沒有(readyState
小於 3)則回傳 null
。
請注意,對於多重請求,這個方法會回傳目前請求的回應而非最早的回應。
getResponseHeader()
以字串型態回傳指定表頭(header),如果沒有(readyState
小於 3)或請求尚未送出則回傳 null
。
header | 回傳指定表頭,例如設定 "Content-Type" ,則返回 application/json; charset=UTF-8、text/plain; charset=UTF-8... 對應的資料類型 |
---|
open()
初始化 HTTP 請求。
method | HTTP 方法,如 GET、POST、PUT 和 DELETE…… |
---|---|
url | 請求目的 URL |
async | (非必填)預設為 true ,代表是否要送出非同步請求。如為 false ,send() 方法於收到回應前不會回傳;如為
true ,透過事件處理器通知請求完成,當在多重請求下,此值必須為 true ,否則會導致例外錯誤 |
user | (非必填)預設為空字串,代表驗證用使用者名稱 |
password | (非必填)預設為空字串,代表驗證用密碼 |
send()
發送 HTTP 請求(request),對於非同步(async)請求會立即回傳,同步(sync)請求則會等到請求完成才回傳。
setRequestHeader()
設定 HTTP 請求表頭(header),必須要在呼叫 open()
後,且在 send()
前呼叫。
header | 表頭名稱(header name),例如設定 Content-Type |
---|---|
value | 表頭值(header value),例如設定 application/x-www-form-urlencoded |
範例
程式
以下將使用 JavaScript 與 jQuery 兩種方式搭配 PHP,來各別實作可查詢、新建員工的 AJAX 應用。
伺服器端 PHP – service.php:
客戶端 JavaScript – javascript-demo.html:
客戶端 jQuery – jquery-demo.html:
下載
參考

本著作係採用創用 CC 姓名標示-相同方式分享 3.0 台灣 授權條款授權.
大大功德無量
謝謝!
透過文章不僅能分享心得,而且在撰寫過程中還能提升一些基本觀念。
難得看到 Client 端和 server 端都完整 po 出來的範例。
謝謝,很實用
想請問一下這ajax範例說明很清楚
但我再跑搜尋到的員工編號 姓名跟性別會顯示NULL是為什麼呢?
還有如果沒輸入東西或輸入錯誤的編號我的程式跑不出錯誤的MSG
只有新增員工時會正常顯示輸出的東西
再請指教一下我新手 感恩~
請問你是直接下載我的程式範例,執行所發生的問題嗎?
您是用 JavaScript 或 jQuery?
您所反應的問題應該是 php 程式的問題,且都是 GET 請求,建議可直接網址列執行 php 程式,並自行加上符合的 GET 參數,來 debug。
如仍無法排除,請再告知。
沒錯是PHP GET程式問題,我在練習您指導的PHP時發現我多打了最下面的 ?> 然後執行get就跑不出東西,POST的部分也會出現NULL,請問一下為何多加?>會導致PHP無法正常回傳呢? 感謝您的指導!
我測試後,不管有無加入 ?> 均沒有發生您的問題,有可能是你 ?> 這附近有用到「全形空白」,造成 php 輸出一些警示訊息,導致 json 無法正確解析。
原則上純 PHP 檔案必須省略 ?> 開關標籤,且檔案結尾必須空一行,至於為什麼可參考 PHP: PHP 标记 - Manual。
建議可直接網址列執行 php 程式,觀查是否輸出了非 json 的 php 警示訊息。
$.ajax({
type: "POST",
url: "service.php",
dataType: "json",
data: {
name: $("#staffName").val(),
number: $("#staffNumber").val(),
sex: $("#staffSex").val()
}
請問如何將POST同時傳給service.php&service2.php
只能傳送給一個 URL。
我目前還未遇到需同時傳送兩個 URL,不知道是在什麼場合需要用到呢?
請問,假如我要做一個連動式的ajax該如何導出陣列資料呢?如:只輸入姓名,導出相關的電話、地址。
html 部分
function ImportAjax(username){
$.ajax({
type: 'POST',
url: 'ajax.php',
data: { user_name: username },
success: function(opt){
$('#user_name').html(opt);
$('#user_tel').html(opt);
$('#user_address').html(opt);
}
});
}
姓名:
電話:
地址:
ajax.php 內容資料
$sql = "SELECT * FROM " . TABLE . " WHERE user_name = '" . $_POST['user_name'] . "' ";
$result = $db->query($sql);
$row = $result->fetch_array();
$result->free();
echo $row['user_name'];
echo $row['user_tel'];
echo $row['user_address'];
MySQL 資料庫裡面有三筆
$a[1]['user_name']='大華'; $a[1]['user_tel']='02-12345'; $a[1]['user_address']='台北市***';
$a[2]['user_name']='小明'; $a[2]['user_tel']='04-54321'; $a[2]['user_address']='台中市***';
$a[3]['user_name']='小美'; $a[3]['user_tel']='06-33445'; $a[3]['user_address']='台南市***';
1. 在輸入姓名的同時 AJAX(配合 JavaScript 的輸入事件)。
2. 如資料庫有符合資料在輸出(建議都統一使用 JSON 格式,因為方便 JavaScript 解析)。
3. 將對應的“電話”與“地址”塞到 html 標記。
如有不了解在互相討論。
感謝站長提示:
我的作法是,如下:
html 部分
function ImportAjax(username){
$.ajax({
type: 'POST',
dataType: 'json',
url: 'ajax.php',
data: { user_name: username },
success: function(opt){
$('#user_name').val(opt.user_name); //輸出姓名
$('#user_tel').html(opt.user_tel); //輸出電話
$('#user_address').val(opt.user_address); //輸出地址
}
});
}
ajax.php 內容資料
$sql = "SELECT * FROM " . TABLE . " WHERE user_name = '" . $_POST['user_name'] . "' ";
$result = $db->query($sql);
$row = $result->fetch_array();
$result->free();
echo json_encode($row);
已完成我的需求!謝謝~~
真是一篇優質的技術文件,大推。
請問如果我要用laravel寫的話
route要怎麼設定
不知道怎麼把這動態的url塞到route裡面
我尚未使用過 Laraval,抱歉。
有基礎又有實做的好文,讀完淚流滿面QQ
很高興對您有幫助
這篇好棒
有幫到您就好~