AJAX ( Asynchronous JavaScript And Xml ) 指的是一套综合了 多项技术的 浏览器端网页开发技术
Ajax 并非一门编程语言;其概念 由 杰西·詹姆斯·贾瑞特( Jesse James Garrett ) 提出
Ajax 组合了 浏览器内建的 XMLHttpRequest 对象( 从 web 服务器请求数据 ) 以及 JavaScript 和 HTML DOM (显示或使用数据)
Ajax 应用程序 可能使用 XML 来传输数据;也可能使用 纯文本 或 JSON 文本 传输数据
Ajax 可以通过 与 场景后面的 web 服务器 交换数据 来 异步更新网页;这意味着,网页可以在不重新加载整个页面前提下,实现网页中部分内容的更新
AJAX 如何工作
大致步骤:
所有现代浏览器 都支持 XMLHttpRequest 对象
Ajax 的核心是 XMLHttpRequest 对象
XMLHttpRequest 对象 用于同幕后服务器 交换数据;这意味着 可以更新 网页的部分,而不需要重新加载整个页面
// 语法
variable = new XMLHttpRequest( );
跨域访问
出于安全原因,现代浏览器不允许跨域访问
即 尝试加载的网页 和 XML 文件 都必须 位于 相同服务器上
属性:
属性 | 描述 |
---|---|
onreadystatechange | 定义当 readyState 属性发生变化时(请求接收到应答)被调用的函数 |
readyState | 保存 XMLHttpRequest 的状态(如下) |
0:请求未初始化 | |
1:服务器连接已建立 | |
2:请求已收到 | |
3:正在处理请求 | |
4:请求已完成且响应已就绪 | |
responseText | 以 字符串 形式返回响应数据 |
responseXML | 以 XML 数据形式返回响应数据 |
status | 返回 请求的状态号(如下部分) |
200:“OK” | |
403: “Forbidden” | |
404: ”Not Found” | |
statusText | 返回状态文本 (诸如 “OK” 或 “Not Found”) |
方法:
方法 | 描述 |
---|---|
abort( ) | 取消当前请求 |
getAllResponseHeaders( ) | 返回头部信息 |
getResponseHeader( ) | 返回特定的头部信息 |
open( method,url,async,user,psw) | 规定请求;method: 请求类型 GET 或 POST;url: 文件位置 |
async: true(异步) 或 false(同步);user/psw: 用户名称/密码 | |
send( ) | 将 请求 发送到 服务器 ,用于 GET请求 |
send( string ) | 将 请求 发送到 服务器,用于 POST 请求 |
setRequestHeader(header , value ) | 向请求添加 HTTP 头部(header:头部名称 ; value:头部值) |
一条 简单的 GET 请求
xhttp.open("GET","demo_get2.asp?fname=Bill&lname=Gates",true);
xhttp.send();
// 用 GET 方法发送 Bill Gates 这条信息
一条 简单的 POST 请求
xhttp.open("POST","ajax_test.asp",true);
xhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhttp.send("fname=Bill&lname=Gates");
// 用 POST 方法发送 Bill Gates 这条信息
// open( ) 方法的 url 参数,是服务器上文件的地址
// 该文件可以是任何类型,如.txt/.xml/.asp/.php等(在发送回响应之前在服务器执行操作)
**回调函数**
回调函数 是一种 **作为参数被传递到另一个函数的** **函数**
如果 网站中有多个 Ajax 任务,应创建 一个执行 XMLHttpRequest 对象的函数 以及 一个供每个 Ajax任务的回调函数(包含URL 以及 当响应就绪时调用的函数)
1. 示例
```js
loadDOC("url-1",myFunction1);
loadDOC("url-2",myFunction2);
function loadDoc(url,cFunction) {
var xhttp;
xhttp = new XMLHttpRequest( );
xhttp.onreadystatechange = function( ) {
if (this.readyState == 4 && this.status == 200 ) {
cFunction( this) ;
}
};
xhttp.open("GET",url,true);
xhttp.send( );
}
function myFunction1(xhttp) {
// action goes here
}
function myFunction2(xhttp) {
// action goes here
}
示例解释:
? 当用户 点击 “获取 CD 信息”按钮时,执行 loadDoc( ) 函数
? loadDoc( ) 函数创建 XMLHttpRequest 对象,添加 当服务器响应就绪时执行的函数,并向服务器发送请求
? 当服务器响应就绪后, 构建HTML表格,从 XML 文件提取节点(因素)
? 最后 使用由XML 数据 填充的 HTML表格 对元素 “demo” 进行更新
示例代码
function loadDoc( ) {
var xhttp = new XMLHttpRequest( );
xhttp.onreadystatechange = function( ) {
if ( this.readyState == 4 && this.status == 200 ) {
myFunciton(this);
}
};
}
function myFunction(xml) {
var i ;
var xmlDoc = xml.responseXML;
var table = "<tr><th>艺术家</th><th>曲目</th></tr>";
var x = xmlDoc.getElementsByTagName("TRACK");
for( i = 0 ; i < x.length ; i ++ ) {
table += "<tr><td>" +
x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue +
"</td></tr>";
}
document.getElementById("demo").innerHTML = table;
}
示例解释:
? 在上面的例子中,当用户在输入字段中键入字符时,会执行名为 “showHint( ) ” 的函数
? 此函数被 onkeyup 事件触发(某个键盘按键被松开)
示例代码
<html>
<head>
<script>
function showHint(str){
if (str.length == 0) {
document.getElementById("txtHint").innerHTML = "";
return;
} else {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadyStatechange = function ( ) {
if (this.readyState == 4 && this.status == 200 ) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xmlhttp.open("GET", "gethint.php?q=" + str ,true);
xmlhttp.send( );
}
}
</script>
</head>
<body>
<p><b>请在下面的输入字段中键入姓名:</b></p>
<form>
姓名:<input type = "text" onkeyup = "showHint(this.value)">
</form>
<p>建议:<span id = "txtHint"></span></p>
</body>
</html>
// gethint.php 文件检查姓名数组,然后向浏览器返回对应的姓名:
<?php
// 姓名数组
$a[] = "Ava";
$a[] = "Brielle";
$a[] = "Caroline";
$a[] = "Diana";
$a[] = "Elise";
$a[] = "Fiona";
$a[] = "Grace";
$a[] = "Hannah";
$a[] = "Ileana";
$a[] = "Jane";
$a[] = "Kathryn";
$a[] = "Laura";
$a[] = "Millie";
$a[] = "Nancy";
$a[] = "Opal";
$a[] = "Petty";
$a[] = "Queenie";
$a[] = "Rose";
$a[] = "Shirley";
$a[] = "Tiffany";
$a[] = "Ursula";
$a[] = "Victoria";
$a[] = "Wendy";
$a[] = "Xenia";
$a[] = "Yvette";
$a[] = "Zoe";
$a[] = "Angell";
$a[] = "Adele";
$a[] = "Beatty";
$a[] = "Carlton";
$a[] = "Elisabeth";
$a[] = "Violet";
// 从 URL 获取 q 参数
$q = $_REQUEST["q"];
$hint = "";
// 查看数组中所有 hint,$q 是否与 "" 相同
if ($q !== "") {
$q = strtolower($q);
$len=strlen($q);
foreach($a as $name) {
if (stristr($q, substr($name, 0, $len))) {
if ($hint === "") {
$hint = $name;
} else {
$hint .= ", $name";
}
}
}
}
// 输出 "no suggestion",如果未找到 hint 或输出正确的值
echo $hint === "" ? "no suggestion" : $hint;
?>
‘gethint.asp 文件检查姓名数组,然后向浏览器返回对应的姓名‘
<%
response.expires=-1
dim a(32)
‘用姓名填充数组
a(1)="Ava"
a(2)="Brielle"
a(3)="Caroline"
a(4)="Diana"
a(5)="Elise"
a(6)="Fiona"
a(7)="Grace"
a(8)="Hannah"
a(9)="Ileana"
a(10)="Jane"
a(11)="Kathryn"
a(12)="Laura"
a(13)="Millie"
a(14)="Nancy"
a(15)="Opal"
a(16)="Petty"
a(17)="Queenie"
a(18)="Rose"
a(19)="Shirley"
a(20)="Tiffany"
a(21)="Ursula"
a(22)="Victoria"
a(23)="Wendy"
a(24)="Xenia"
a(25)="Yvette"
a(26)="Zoe"
a(27)="Angell"
a(28)="Adele"
a(29)="Beatty"
a(30)="Carlton"
a(31)="Elisabeth"
a(32)="Violet"
‘从 URL 获取 q 参数
q=ucase(request.querystring("q"))
‘查看数组中所有 hint,q 的长度是否大于 0
if len(q)>0 then
hint=""
for i=1 to 30
if q=ucase(mid(a(i),1,len(q))) then
if hint="" then
hint=a(i)
else
hint=hint & " , " & a(i)
end if
end if
next
end if
‘如果未找到 hint,输出 "no suggestion",或输出正确的值
if hint="" then
response.write("no suggestion")
else
response.write(hint)
end if
%>
当用户在上面的下拉列表中选择一位客户后,执行名为“ showCustomer( )” 函数
此函数被 onchange 事件触发:
示例
function showCustomer(str) {
var xhttp;
if (str == "") {
document.getElementById("txtHint").innerHTML = "";
return;
}
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xhttp.open("GET", "getcustomer.asp?q=" + str, true);
xhttp.send();
}
// showCustomer( ) 函数执行逻辑如下:
// 1. 检查是否选取客户
// 2. 创建 XMLHttpRequest 对象
// 3. 创建当服务器响应就绪时执行的函数
// 4. 向服务器上的文件发送请求
// * 请注意,参数q 被添加到URL (带有下拉列表的内容)
‘getcustomer.asp 中的源代码中运行米面向数据库的查询,并在HTML表格中返回结果‘
<%
response.expires=-1
sql="SELECT * FROM CUSTOMERS WHERE CUSTOMERID="
sql=sql & "‘" & request.querystring("q") & "‘"
set conn=Server.CreateObject("ADODB.Connection")
conn.Provider="Microsoft.Jet.OLEDB.4.0"
conn.Open(Server.Mappath("customers.mdb"))
set rs=Server.CreateObject("ADODB.recordset")
rs.Open sql,conn
response.write("<table>")
do until rs.EOF
for each x in rs.Fields
response.write("<tr><td><b>" & x.name & "</b></td>")
response.write("<td>" & x.value & "</td></tr>")
next
rs.MoveNext
loop
response.write("</table>")
%>
JSON( JavaScript Object Notation) JavaScript对象标记法;最初由 Douglas Crockford 提出
JSON 属于 文本(文本可被任何编程语言作为数据来读取和使用),是一种 存储和交换数据 的语法
JSON 是一种 轻量级的 数据交换格式;独立于语言;且具有自我描述、易于理解的特点
JSON 文件 的 文件类型 是 “.json”
JSON 文本 的 MIME ( Mulitpurpose Internet Mail Extensions 媒体类型 ) 类型 是 “application/json”
(MIME 类型 又称 互联网媒体类型 ,是一种标准;用来表示文档、文件或字节流的性质和格式)
因为 JSON 格式仅仅是 文本,它能够轻松地在 服务器浏览器之间传输,并用作任何编程语言的数据格式
JavaScript 提供内建函数 把以 JSON 格式写的字符串 转换为 原生 JavaScript 对象
语法
JSON.parse( ); // JSON →→→ JavaScript
JSON.stringify( ); // JavaScript →→→ JSON
因此,从服务器以 JSON 接收到的数据,可以像任何其它 JavaScript 对象那样使用它
若数据 存储在 JavaScript 对象中,应把对象 转换为 JSON ,然后将其发送到 服务器
示例代码
var myObj = { name:"Bill Gates",age:62,city:"Seattle"};
var myJSON = JSON.stringify(Obj);
window.location = "demo_json.php?x=" + myJSON;
// 通过 JSON.stringify( ) 把 JavaScript 对象转换为字符串
// 通过 JSON.stringify( ) 把 数组转换为字符串
var arr = ["Bill Gates","Steve Jobs","Elon Musk"];
var myJSON = JSON.stringify(arr);
document.getElementById("demo").innerHTML = myJSON;
// 通过 JSON.stringify 把 日期字符串化
var obj = {"name":"Bill Gates", "today":new Date( ),"city":"Seattle"};
var myJSON = JSON.stringify(obj);
document.getElementById("demo").innerHTML = myJSON
// 返回 {"name":"Bill Gates","today":"2021-01-31T02:56:12.709Z","city":"Seattle"}
若以 JSON 格式 接收到数据, 可将其 转换为 原生的 JavaScript 对象
示例代码
var myJSON = ‘{ "name":"Bill Gates","age":62,"city":"Seattle"}‘;
var myObj = JSON.parse(myJSON);
document.getElementById("demo").innerHTML = myObj.name;
// 通过 JSON.parse( ) 解析从服务器接收到的数据字符串
// 使用 AJAX 请求从服务器 请求JSON
var xmlhttp = new XMLHttpRequest( );
xmlhttp.onreadystatechange = function( ) {
if ( this.readyState == 4 && this.status == 200 ) {
myObj = JSON.parse( this.responseText);
document.getElementById("demo").innerHTML = myObj.name;
}
};
xmlhttp.open( "GET","json_demo.txt",true);
xmlhttp.send( );
// 在 对衍生自数组的 JSON 使用 JSON.parse( )后,此方法返回 JavaScript 数组,而非对象
var xmlhttp = new XMLHttpRequest( );
xmlhttp.onreadystatechange = function( ) {
if ( this.readyState == 4 && this.status == 200 ) {
myArr = JSON.parse( this.responseText);
document.getElementById("demo").innerHTML = myObj.name;
}
};
xmlhttp.open( "GET","json_demo_array.txt",true);
xmlhttp.send( );
在存储数据时,数据必须是某种具体的格式
并且 无论您 选择 在何处存储它,文本永远是 合法格式之一
JSON 让 JavaScript 对象 存储为 文本 成为可能!
代码示例
// 存储数据
myObj = {name: "Bill Gates",age: 62,city: "Seattle"};
myJSON = JSON.stringify(myObj);
localStorage.setItem("testJSON",myJSON);
// 接收数据
text = localStorage.getItem("testJSON");
obj = JSON.parse(text);
document.getElementById("demo").innerHTML = obj.name;
JSON 语法 衍生于 JavaScript 对象标记的语法
JSON 数据 写为 名称/值对;名称/值对 由 字段名称构成,后跟冒号和值
JSON 名称 需要双引号,而 JavaScript 名称不需要
示例代码
// 在 JSON 中, 键 必须是字符串,由双引号包围
{"name":"Bill Gates"};
// 在 JavaScript中,键 可以是字符串、数字或标识符名称
{name: "Bill Gates"}
在 JSON 中, 值必须是以下 数据类型 之一
在 JavaScript 中,以上所列均可为值,外加其它有效地 JavaScript 表达式,包括:
在 JSON 中, 字符串 必须用 双引号编写;而在 JavaScript 中 可使用 双引号/单引号 的字符串值
JSON 和 XML 均可用于 从 web服务器 接收数据
示例代码
// json 定义 一个由3个雇员构成的 雇员对象
{"employees":[
{"firstName":"Bill","lastName":"Gates"},
{"firstName":"Steve","lastName":"Jobs"},
{"firstName":"Elon","lastName":"Musk"}
]}
<!-- xml 定义 一个由3个雇员构成的 雇员对象-->
<employees>
<employee>
<firstName>Bill</firstName>
<lastName>Gates</lastName>
</employee>
<employee>
<firstName>Steve</firstName>
<lastName>Jobs</lastName>
</employee>
<employee>
<firstName>Elon</firstName>
<lastName>Musk</lastName>
</employee>
</employees>
JSON 与 XML 相同点
JSON 与 XLM 的差异
JSON 相对于 XML 的优势
JSON 对象的大多语法 都跟 JavaScript 一致
访问对象值
myObj = {"name":"Bill Gates","age":62,"car":null};
x = myObj.name;
x = myObj["name"];
// 可以通过(.)或([])来访问对象值
遍历对象
myObj = {"name":"Bill Gates","age":62,"car":null};
for ( x in myObj ) {
document.getElementById("demo").innerHTML += myObj[x] ;
}
// 可以通过 for-in 遍历对象属性;请使用括号标记法 myObj[x]
嵌套 JSON 对象
myObj = {
"name":"Bill Gates",
"age":62,
"cars":{
"car1":"Porsche",
"car2":"BWM",
"car3":"Volvo"
}
}
x = myObj.cars.car2;
x = myObj.cars["car2"];
// 通过(.)或([]) 访问嵌套的JSON对象属性
myObj.cars.car3 = "Mercedes Benz";
myObj.cars.["car3"] = "Mercedes Benz";
// 通过(.)或([]) 修改JSON嵌套对象中的值
delete myObj.cars.car1;
// 通过 delete 关键词 来删除 JSON嵌套对象的属性
JSON 中的 数组 几乎与 JavaScript 中的数组相同
var arr = {
"name":"Bill Gates",
"age":62,
"car":["Porsche","BWM","Volvo"]
}
x = arr.car[0];
// 通过 索引来访问 数组的元素值
for ( i = 0 ; i < arr.length ; i ++) {
var x += myObj.cars[i];
}
// 通过 for 循环遍历数组
var arrs = {
"name":"Bill Gates",
"age":62,
"cars":[
{"name":"Porsche","models":["911","Taycan"]},
{"name":"M5","models":["M5","M3","X5"]},
{"name":"Volvo","models":["XC60","V60"]}
]
}
// 数组中的值 可以是另一个数组;甚至可以是另一个 JSON 对象
// 访问数组内的数组,应对 每个数组分别使用 for-in 循环
var i,x,j;
for( i in arrs.cars) {
x += "<h1>" + arrs.cars[i].name + "</h1>";
for ( j in arrs.cars[i].models ) {
x += arrs.cars[i].models[j];
}
}
// 通过 索引号来修改数组元素值
arrs.cars[1] = "Mercedes Benz";
// 通过 delete 关键词来删除数组中的项目
delete arrs.cars[2];
JSON 的常规用途 是从 web 服务器读取数据,然后在 网页中显示这些数据
那么,如何在 客户端 与 PHP 服务器之间交换 JSON 数据 ?
PHP 提供处理 JSON 的内建函数
通过使用 PHP 函数 json_encode( ) ,PHP 中的对象可转换为 JSON
<?php
$myObj->name = "Bill Gates";
$myObj->age = 62;
$myObj->city = "Seattle";
$myJSON = json_encode($myObj);
echo $myJSON;
?>
客户端上的 JavaScript ,使用 AJAX 调用来请求上例 的 PHP 文件
使用 JSON.parse( ) 把 结果转换为 JavaScript 对象
var xmlhttp = new XMLHttpRequest( );
xmlhttp.onreadystatechange = function ( ) {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myObj.name;
}
};
xmlhttp.open("GET","demo_file.php",true);
xmlhttp.send( );
在 使用 PHP 函数 json_encode( ) 时, PHP 中的 数组 也将被转换为 JSON
<?php
$myArr = array("Bill Gates","Steve Jobs","Elon Musk");
$myJSON = json_encode($myArr);
echo $myJSON;
?>
var xmlhttp = new XMLHttpRequest( );
xmlhttp.onreadystatechange = function ( ) {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
document.getElementById("demo").innerHTML = myObj[2];
}
};
xmlhttp.open("GET","demo_file_array.php",true);
xmlhttp.send( );
PHP 是 服务器端 编程语言,应该用于只能由服务器执行的操作,比如访问数据库
问题:
假设服务器上有一个数据库,包含 客户、产品 和 供应商数据
此刻,您需要请求服务器来 获取 “客户” 表中 前10条数据记录
var obj,dbParam,xmlhttp;
obj = {"table":"customer","limit":10};
dbParam = JSON.stringify(obj);
xmlhttp = new XMLHttpRequest( );
xmlhttp.onreadystatechange = function( ) {
if(this.readyState == 4 && this.status == 200 ) {
document.getElementById("demo").innerHTML = this. responseText;
}
};
xmlhttp.open("POST","demo_json_db.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("x=" + dbParam);
// 代码解释:
// 定义包含 table 属性 和 limit 属性的 对象 obj
// 将这个对象 转换为 JSON 字符串
// 向这个 PHP 文件发送请求,其中 JSON 作为参数 demo_json_db.php
// 等待直到请求返回结果(作为 JSON)
// 显示 从 PHP 文件接收到的结果
// 需要注意的是:
// 在向服务器发送数据时,通常最好是使用 HTTP POST 方法
// 若用 POST 方法 来发送 AJAX 请求,需要指定该方法和正确的头部
// 发送到服务器的数据现在必须是 .send( )方法的参数
demo_json_db.php 文件
<?php
header("Centent-Type:application/json:cahrset = UTF-8");
$obj = json_decode($_POST["x"],false);
$conn = new mysqli("mySever","myUser","myPassword","Northwind");
$result = $conn->query("SELECT name FROM ".$obj->table."LIMT".$obj->$limit);
$outp = array( );
$outp = $result->fetch_all(MYSQLI_ASSOC);
echo json_encode($outp);
?>
// 将请求 转换为 对象,使用 PHP 函数 json_decode( )
// 访问数据库,用所请求的数据填充数组
// 把数组添加对象,使用 json_encode( ) 函数以 JSON 返回该对象
把 从 PHP 文件接收到的结果 转换为 JavaScript 对象;本例中,为一个 JavaScript 数组
...
var x ,txt = "",myObj;
xmlhttp.onreadystatechange = function ( ) {
if(this.readyState == 4 && this.status == 200 ) {
myObj = JSON.parse(this.responseText);
for( x in myObj) {
txt += myObj[x].name +"<br>";
}
document.getElementById("demo").innerHTML = txt;
}
};
...
代码示例
<script>
var xmlhttp, myObj, x, txt = "";
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myObj = JSON.parse(this.responseText);
for (x in myObj) {
txt += myObj[x].CustomerId + "<br>";
}
document.getElementById("demo").innerHTML = txt;
}
};
xmlhttp.open("POST", "/demo/demo_json_db.php", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send();
</script>
JSONP ( JSON with Padding ) 是 一种 无需考虑跨域问题 即可传送 JSON 数据的方法
从另一个 域 请求文件 会引起问题,由于跨域政策
从 另一个 域 请求外部脚本没有这个问题
JSONP 不使用 XMLHttpRquest 对象;使用 <script>
标签 取而代之
<script src = documentName.php>
待续……
原文:https://www.cnblogs.com/newcheer/p/14354180.html