AJAX JavaScript 与 jQuery 案例 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 处理服务器响应的资料,因只取须要的资料,所以服务器回应更快且负荷也减少了。

使用 JavaScript 实时与服务器进行少量资料交换,来异步局部更新网页

AJAX 运作原理

  1. 用户在浏览器触发一个事件,例如点击按钮

  1. 将上述获的事件的同时,使用 JavaScript 的对象,在背景对「Web 服务器」发送一个 HTTP 请求,达到与「Web 服务器」进行数据的异步交换XMLHttpRequest

  1. 将从「Web 服务器」取得的资料,使用 JavaScript 操作 DOM,来实现动态局部更新「浏览器」的网页内容

HTTP


完整的 HTTP 流程

一个完整的 HTTP 流程,通常有下面七个步骤:

  1. 建立 TCP 连接

  1. 浏览器:向「Web 服务器」发送请求命令

  1. 浏览器:发送请求表头(headers)

  1. Web 服务器:回應(response)

  1. Web 服务器:发送回应(response)信息

  1. Web 服务器:向浏览器发送资料

  1. Web 服务器:关闭 TCP 连接

HTTP 請求方法(GET 與 POST)

获取
  • 适用于信息获取(查询结果)

  • 使用 URL 传递参数(name=value)

  • 对所发送信息的数量有限制,一般在2,000个字串

传递参数(name=value)都在 URL 中,任何人都可见

发布
  • 适用于修改服务器上的资料

  • 所有传递的参数(name=value)将被嵌入 HTTP 的请求主体(body)

  • 对所发送信息的数量无限制

传递参数(name=value)不可见

HTTP 請求(request)

一个 HTTP 请求由四个部分构成:

  1. HTTP 请求方法(method)或「动词」(verb),比如是 GET 或 POST 请求

  1. 要请求的 URL,就是请求的网址

  1. 一组选择性的请求表头(headers),包含一些「客户端环境」与「身份验证」信息...

  1. 一个选择性的请求主体(body),也就是请求正文,可包含客户提交的「查询字符串」或「表单」信息...

HTTP 请求内容
  • 请求方法:GET

  • 请求地址:/service.php?number=1020501

  • HTTP 版本:HTTP/1.1

  • 请求表头:红框部分

  • 请求主体:绿框部分

请求「表头」与「主体」之间有一个空行,用来表示请求「表头」已经结束了,接下来是请求「主体」

GET/service.php?number=1020501 HTTP/1.1

Host: 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)有三个部分:

  1. 由数值与文字所组成的状态码(status code),指示请求成功或失败

  1. 一组响应表头(headers)包含许多有用的信息,例如服务器类型、日期时间、内容类型和长度...

  1. 回应主体(body)也就是回应正文,例如“文字字符串”或“HTML 代码”...

http 回应内容
  • HTTP 版本:HTTP/1.1

  • 回应状态码:200 OK,代表请求成功

  • 回应数据类型:application/json; charset=UTF-8,代表数据类型 JSON; 编码格式 UTF-8

  • 回应表头:红框部分

  • 回应主体:绿框部分(这里回应的资料格式为 JSON)

回应「表头」与「主体」之间有一个空行,用来表示回应「表头」已经结束了,接下来是回应「主体」

HTTP/1.1 200 OK

Date: 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 定义在一个 对象之上。 此对象的每个实体皆代表一组 request / response 的配对,而这个对象的「属性」与「方法」让你能够:XMLHttpRequest

  • 做出POST、HEAD及普通GET请求(request)的能力

  • 同步(sync)或异步(async)提取 Web 服务器的响应(response),并且能够以「文字」或一个「DOM」文件... 的形式返回内容

XMLHttpRequest 它并不限于只能用在 XML 文件,它可以接收任何形式的文字档案

构造子(constructor)

XMLHttpRequest()

呼叫任何方法前一定要先调用构造子,例如:

var request =XMLHttpRequest();

JavaScript复制

浏览器支持

XMLHttpRequest 对象第一次的出现是在 Microsoft 的 IE5 中,但在 IE5 及 IE6 中它是以 对象的形式提供。 现在标准的 构建子在IE7之前并没有支持(现代浏览器都有支持),但可这样模拟它的功能,以兼容所有浏览器(包含IE7之前):ActiveXXMLHttpRequest()

// 建立 Ajax 物件
request =newajaxRequest();functionajaxRequest(){try{// (除 IE7 之前)支援所有現代瀏覽器var request =newXMLHttpRequest();}catch(e1){try{// (支援 IE6)如果有的話就用 ActiveX 物件的最新版本
            request =newActiveXObject("Msxml2.XMLHTTP.6.0");}catch(e2){try{// (支援 IE5)否則就用較舊的版本
                request =newActiveXObject("Msxml2.XMLHTTP.3.0");}catch(e3){// 不支援 Ajax,拋出錯誤thrownewError("XMLHttpRequest is not supported");}}}return request;}

JavaScript复制

属性(attribute)

就绪状态

HTTP 请求的状态,当一个 初次建立时,这个属性的值为 0,直到接收到完整的 HTTP 回应(response),则值增加到 4。XMLHttpRequest

JavaScript XMLHttpRequest readyState 值

状态

描述

0

未发送

open() 尚未被呼叫

1

OPEND

open() 方法已被呼叫,但 方法未被呼叫send()

2

HEADERS_RECEIVED

send() 方法已被呼叫,而且可取得 header 与状态

3

装载

回应数据下载中,此时会拥有部分资料responseText

4

回应(response)已经完成

响应文本

响应请求的字符串资料; 如果请求失败或尚未完成,则为 。null

响应XML

响应请求的 DOM 文档对象(Document Object),如果请求失败、尚未完成或回传数据无法解析为 XML 或 HTML 文件,则为 。 回应会如同 text / html 一般一样被解析。 当 被设为 “document” 而且请求不是异步,回应会如同 text / html 一般一样被解析。nullresponseType

地位

请求回应状态,也就是 HTTP 状态码(status code),例如:200 代表成功; 404 NOT Found,代表请求中引用的档案不存在。

状态文本

与 不一样的是回应状态字串(Status String),且会包含完整的回传讯息,例如:“200 OK”; "404 NOT Found"。status

事件(event)

就绪状态更改

当 属性每次改变时呼叫的 JavaScript 函数,是从用户界面的线程中呼叫。readyState

方法(method)

中止()

终止送出的请求。

这个方法会将属性重置为 0,回应不再必要的时候,可以呼叫这个方法。readyState

getAllResponseHeaders()

以字符串类型返回所有响应表头(response headers),如果没有( 小于 3)则返回 。readyStatenull

请注意,对于多重请求,这个方法会回传目前请求的回应而非最早的回应。

DOMString getAllResponseHeaders();

JavaScript复制

getResponseHeader()

以字符串类型返回指定表头(header),如果没有( 小于 3)或请求尚未发送回传 。readyStatenull

DOMString getResponseHeader(DOMString header);

JavaScript复制

JavaScript XMLHttpRequest getResponseHeader() 参数

页眉

回传指定表头,例如设定 “Content-Type” ,则返回 application/json; charset=UTF-8、text/plain; charset=UTF-8... 对应的数据类型

打开()

初始化 HTTP 请求。

voidopen(
    DOMString method,
    DOMString url,
    optional boolean async,
    optional DOMString user,
    optional DOMString password
);

JavaScript复制

JavaScript XMLHttpRequest open() 参数

方法

HTTP 方法,如 GET、POST、PUT 和 DELETE……

网址

请求目的 URL

异步

(非必填)默认为 ,代表是否要送出异步请求。 如为 , 方法于收到回应前不会回传; 如为 ,透过事件处理器通知请求完成,当在多重请求下,此值必须为 ,否则会导致例外错误truefalsesend()truetrue

用户

(非必填)默认为空字符串,代表验证用户名

密码

(非必填)默认为空字符串,代表验证用密码

发送()

发送 HTTP 请求(request),对于异步(async)请求会立即回传,同步(sync)请求则会等到请求完成才回传。

voidopen(
    DOMString method,
    DOMString url,
    optional boolean async,
    optional DOMString user,
    optional DOMString password
);

JavaScript复制

setRequestHeader()

设定 HTTP 请求表头(header),必须要在呼叫后,且在 前呼叫。open()send()

使用 POST 方法必须设定 HTTP 请求表头(header),GET 方法则不须设定

voidsetRequestHeader(
    DOMString header,
    DOMString value
);

JavaScript复制

JavaScript XMLHttpRequest setRequestHeader() 参数

页眉

表头名称(header name),例如设定 Content-Type

价值

表头值(header value),例如设定 application/x-www-form-urlencoded

范例


程式

以下将使用 JavaScript 与 jQuery 两种方式搭配 PHP,来各别实作可查询、新建员工的 AJAX 应用。

示例使用 JSON 作为「资料交换格式」,可参考 JSON 格式与 JavaScript 解析教学范例

JavaScript 与 jQuery 所使用的 PHP 代码都相同

伺服器端 PHP – service.php:

<?php// 設置資料類型 json,編碼格式 utf-8header('Content-Type: application/json; charset=UTF-8');// 定義一個二維陣列來儲存員工資料,每筆員工資料為一個陣列$staff=array(array('number'=>'1020501','name'=>"王一傑",'sex'=>'男'),array('number'=>'1020502','name'=>"王二傑",'sex'=>'男'),array('number'=>'1020503','name'=>"王三傑",'sex'=>'男'));// 判斷如果是 GET 請求,則進行搜尋;如果是 POST 請求,則進行新建// $_SERVER['REQUEST_METHOD'] 返回訪問頁面使用的請求方法if($_SERVER['REQUEST_METHOD']=="GET"){search($staff);}elseif($_SERVER['REQUEST_METHOD']=="POST"){create();}// 通過員工編號搜尋functionsearch($staff){// 檢查是否有員工編號的參數// isset() 方法檢測變數是否設置;empty() 方法判斷值是否為空// 超全域變數 $_GET 和 $_POST 用於收集表單資料if(!isset($_GET['number'])||empty($_GET['number'])){echojson_encode(array('msg'=>'沒有輸入員工編號!'));return;}// 搜尋員工編號for($i=0,$len=count($staff);$i<$len;$i++){// 如果存在,儲存對應的陣列if($staff[$i]['number']==$_GET['number']){$result=$staff[$i];}}// 將陣列編碼成 JSON 字串echoisset($result)?json_encode($result):json_encode(array('msg'=>'沒有該員工!'));}// 新建員工functioncreate(){// 如果員工資料未填寫完全if(!isset($_POST['number'])||empty($_POST['number'])||!isset($_POST['name'])||empty($_POST['name'])||!isset($_POST['sex'])||empty($_POST['sex'])){echojson_encode(array('msg'=>'員工資料未填寫完全!'));return;}// 可將獲取的 POST 表單資料,儲存到資料庫(該部分未實作)// 儲存成功,返回員工姓名echojson_encode(array('name'=>$_POST['name']));}

.PHP复制

客户端 JavaScript – javascript-demo.html:

<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><title>JavaScript Ajax Demo</title><style type="text/css"> 
input, button, select {
    margin-bottom: 10px;}</style></head><body><h1>查詢員工</h1><label for="keyword">請輸入員工編號:</label><input type="text" id="keyword"><button id="search">查詢</button><p id="searchResult"></p><h1>新建員工</h1><label for="staffNumber">請輸入員工編號:</label><input type="text" id="staffNumber"><br><label for="staffName">請輸入員工姓名:</label><input type="text" id="staffName"><br><label for="staffSex">請輸入員工性別:</label><select id="staffSex"><option value="男">男</option><option value="女">女</option></select><br><button id="save">保存</button><p id="createResult"></p><script type="text/JavaScript">
document.getElementById("search").onclick=function(){// 發送 Ajax 查詢請求並處理var request =newXMLHttpRequest();
    request.open("GET","service.php?number="+ document.getElementById("keyword").value);
    request.send();

    request.onreadystatechange=function(){// 伺服器請求完成if(request.readyState ===4){// 伺服器回應成功if(request.status ===200){var type = request.getResponseHeader("Content-Type");// 取得回應類型// 判斷回應類型,這裡使用 JSONif(type.indexOf("application/json")===0){var data =JSON.parse(request.responseText);if(data.number){
                        document.getElementById("searchResult").innerHTML ='[找到員工] 員工編號:'+data.number +', 姓名:'+
                                                                                data.name +', 性別:'+ data.sex;}else{
                        document.getElementById("searchResult").innerHTML = data.msg;}}}else{alert("發生錯誤: "+ request.status);}}}}

document.getElementById("save").onclick=function(){// 發送 Ajax 查詢請求並處理var request =newXMLHttpRequest();
    request.open("POST","service.php");// POST 參數須使用 send() 發送var data ="name="+ document.getElementById("staffName").value +"&number="+ document.getElementById("staffNumber").value +"&sex="+ document.getElementById("staffSex").value;// POST 請求必須設置表頭在 open() 下面,send() 上面
    request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    request.send(data);

    request.onreadystatechange=function(){// 伺服器請求完成if(request.readyState ===4){// 伺服器回應成功if(request.status ===200){var type = request.getResponseHeader("Content-Type");// 取得回應類型// 判斷回應類型,這裡使用 JSONif(type.indexOf("application/json")===0){var data =JSON.parse(request.responseText);if(data.name){
                        document.getElementById("createResult").innerHTML ='員工:'+ data.name +',儲存成功!';}else{
                        document.getElementById("createResult").innerHTML = data.msg;}}}else{alert("發生錯誤"+ request.status);}}}}</script></body></html>

JavaScript复制

客户端 jQuery – jquery-demo.html:

<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><title>jQuery Ajax Demo</title><style type="text/css"> 
input, button, select {
    margin-bottom: 10px;}</style></head><body><h1>查詢員工</h1><label for="keyword">請輸入員工編號:</label><input type="text" id="keyword"><button id="search">查詢</button>
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值