原生Ajax:
Ajax基礎:
--ajax:無刷新數據讀取,讀取服務器上的信息
--HTTP請求方法:
--GET:用於獲取數據,如瀏覽帖子
--POST:用於上傳數據,如用戶注冊
--GET與POST的區別:
GET:--通過網址傳遞(放入url中),會將傳遞的數據放到網址上面,--名字=值&名字=值
--get方式容量小
--安全性低
--有緩存
POST:--不通過網址傳遞
--post容量較大,一般可達2G
--安全性相對較高
--沒有緩存
原生Ajax的編寫:
Ajax運行步驟:
1.創建一個Ajax對象
非IE6瀏覽器:var oAjax=new XMLHttpRequest();
IE6瀏覽器:var oAjax=new ActiveXObject("Microsoft.XMLHTTP");
2.連接到服務器
oAjax.open(方法,文件名,異步傳輸);
阻止緩存方法:
oAjax.open('GET','a.txt?t='+new Date().getTime(),true);
--同步:js中指事情必須一件一件來
--異步:js中指多件事情要一起做
--ajax是做異步傳輸的,並不是同步
3.發送請求
oAjax.send();
4.接收返回值
請求狀態監控:onreadystatechange事件:當自己的Ajax與服務器之間有通訊時觸發
主要通過readyState屬性來判斷結束沒有,結束了也並沒有代表成功,status屬性來判斷
1.--readyState屬性:請求狀態
--0(未初始化)還沒有調用open方法
--1(載入)已經調用send()方法,正在發送請求
--2(載入完成)send()方法完成,已經收到全部相應內容
--3(解析)正在解析收到的響應內容
--4(完成)響應內容解析完成,可以在客戶端調用(完成並不一定成功,需要status來檢測是成功還是失敗)
2.--status屬性:請求結果,是成功(200)還是失敗(404):oAjax.status==200
3.--返回值responseText:從服務器返回來的文本:oAjax.responseText
(返回的值是一個字符串,有時需要進一步處理成其他格式的形式)
oAjax.onreadystatechange=function(){
//oAjax.readyState: 表示瀏覽器和服務器之間進行到哪一步了
if(oAjax.readyState==4){ //讀取完成
if(oAjax.status==200){ //讀取的結果是成功
alert('成功:'+oAjax.responseText);
}
}
}
將原生Ajax封裝成一個函數使用,最終編寫的原生Ajax為:
1) GET方法封裝的函數為:
function ajax(url,fnSuccess,fnFaild){
//1.創建Ajax對象
//js中,使用一個沒有定義的變量會報錯,使用一個沒有定義的屬性,是undefined
//IE6下使用沒有定義的XMLHttpRequest會報錯,所以當做window的一個屬性使用
if (window.XMLHttpRequest) {
//非IE6
var oAjax=new XMLHttpRequest();
}else{
//IE6
var oAjax=new ActiveXObject("Microsoft.XMLHTTP");
}
//2.連接到服務器
oAjax.open('GET',url,true);
//3.發送請求
oAjax.send();
//4.接收返回值
oAjax.onreadystatechange=function(){
//oAjax.readyState--瀏覽器和服務器之間進行到哪一步了
if(oAjax.readyState==4){ //讀取完成
if(oAjax.status==200){ //讀取的結果是成功
fnSuccess(oAjax.responseText); //成功時執行的函數
}else{
if(fnFaild){ //判斷是否傳入失敗是的函數,即用戶是否關心失敗時的結果
fnFaild(oAjax.responseText); //對失敗的原因做出處理
}
}
}
}
}
2)POST方法封裝的函數為:
function ajaxPost(url,id,fnSuccess,fnFaild){
//1.創建Ajax對象
if (window.XMLHttpRequest) {
//非IE6
var xhr=new XMLHttpRequest();
}else{
//IE6
var xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
//2.連接到服務器
xhr.open("POST",url,true);
//設置頭信息
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
var form=document.getElementById(id);
//3.發送請求,傳遞數據
xhr.send(serialize(form));
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if ((xhr.status>=200 && xhr.status<300) || xhr.status==304) {
fnSuccess(xhr.responseText);
}else{
fnFaild(xhr.responseText);
}
}
};
}
注**
1--字符集編碼:網頁和被請求的文件的編碼要相同,如都是utf8
2--緩存,阻止緩存(經常改變的數據等,不能夠緩存.主要用於GET方法)
--傳參時在路徑后面加?+'可變的數據' 可以不影響原數據
ajax('a.txt?t='+new Date().getTime(),function(str){
alert(str);
},function(str){
alert(str);
});
3--ajax請求動態數據:如json文件
3.1--ajax返回值是一個字符串,可通過eval轉換后來讀取返回的數組/json數據
alert(str);
alert(typeof(str));
var arr=eval(str);
alert(typeof(arr));
alert(arr[1]);
alert(arr[1].c);
3.2--結合DOM創建元素,來顯示返回的內容
oBtn.onclick=function(){
ajax('data/arr3.txt?t='+new Date().getTime(),function(str){
var arr=eval(str);
for (var i = 0; i < arr.length; i++) {
var oLi=document.createElement('li');
oLi.innerHTML='用戶名:<span>'+arr[i].user+'</span>密碼:<span>'+arr[i].pass+'</span>';
oUl.appendChild(oLi);
}
},function(str){
alert(str);
});
}
4--數據類型-->返回的數據類型可能是xml(幾乎已經淘汰),json(現在常用)
示例1:原生Ajax向服務器請求數據(即GET方法)
data/arr3.txt為:[{user:'blue',pass:'123'},{user:'red',pass:'234'},{user:'yellow',pass:'567'}]
1 HTML代碼: 2 <input type="button" name="" value="按鈕" id="btn1">
3 <ul id="ul"></ul>
4
5
6 JS代碼: 7 <script type="text/javascript">
8 var oBtn=document.getElementById('btn1'); 9 var oUl=document.getElementById('ul'); 10
11 oBtn.onclick=function(){ 12 ajax('data/arr3.txt?t='+new Date().getTime(),function(str){ 13 var arr=eval(str); 14 for (var i = 0; i < arr.length; i++) { 15 var oLi=document.createElement('li'); 16 oLi.innerHTML='用戶名:<span>'+arr[i].user+'</span>密碼:<span>'+arr[i].pass+'</span>'; 17 oUl.appendChild(oLi); 18 } 19 },function(str){ 20 alert(str); 21 }); 22 }; 23
24
25 function ajax(url,fnSuccess,fnFaild){ 26 //1.創建Ajax對象
27 //js中,使用一個沒有定義的變量會報錯,使用一個沒有定義的屬性,是undefined
28 //IE6下使用沒有定義的XMLHttpRequest會報錯,所以當做window的一個屬性使用
29 if (window.XMLHttpRequest) { 30 //非IE6
31 var oAjax=new XMLHttpRequest(); 32 }else{ 33 //IE6
34 var oAjax=new ActiveXObject("Microsoft.XMLHTTP"); 35 } 36 //2.連接到服務器
37 oAjax.open('GET',url,true); 38 //3.發送請求
39 oAjax.send(); 40 //4.接收返回值
41 oAjax.onreadystatechange=function(){ 42 //oAjax.readyState--瀏覽器和服務器之間進行到哪一步了
43 if(oAjax.readyState==4){ //讀取完成
44 if(oAjax.status==200){ //讀取的結果是成功
45 fnSuccess(oAjax.responseText); //成功時執行的函數
46 }else{ 47 if(fnFaild){ //判斷是否傳入失敗是的函數,即用戶是否關心失敗時的結果
48 fnFaild(oAjax.responseText); //對失敗的原因做出處理
49 } 50 } 51 } 52 } 53 } 54 <script>
示例2:原生Ajax向服務器發送數據(即POST方法)
這里用到了表單序列化,將表單序列化之后再傳遞給后台,序列化內容見博客“表單序列化”。
后台數據:data/postexample.php
<?php
header("Content-Type:text/plain");
echo <<<EOF
Name:{$_POST['username']}
Email:{$_POST['userpass']}
EOF;
?>
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>原生ajaxPost</title> 8 </head> 9 <body> 10 <form id="user-info"> 11 <label>用戶名:</label><input type="text" name="username" value=""> 12 <label>密碼:</label><input type="text" name="userpass" value=""> 13 <input type="button" name="" value="按鈕2" id="btn2"> 14 </form> 15 16 17 <script type="text/javascript"> 18 window.onload=function(){ 19 var oBtn2=document.getElementById('btn2'); 20 var oUl=document.getElementById('ul'); 21 22 oBtn2.onclick=function(){ 23 ajaxPost('data/postexample.php?t='+new Date().getTime(),"user-info",function(str){ 24 //當后台返回的是json數據時,可以用eval(函數來處理),與get方法類似 25 alert(str); 26 },function(str){ 27 alert(str); 28 }); 29 }; 30 } 31 32 33 //封裝的ajaxPost函數 34 function ajaxPost(url,id,fnSuccess,fnFaild){ 35 //1.創建Ajax對象 36 if (window.XMLHttpRequest) { 37 //非IE6 38 var xhr=new XMLHttpRequest(); 39 }else{ 40 //IE6 41 var xhr=new ActiveXObject("Microsoft.XMLHTTP"); 42 } 43 //2.連接到服務器 44 xhr.open("POST",url,true); 45 //設置頭信息 46 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); 47 var form=document.getElementById(id); 48 //3.發送請求,傳遞數據 49 xhr.send(serialize(form)); 50 xhr.onreadystatechange=function(){ 51 if(xhr.readyState==4){ 52 if ((xhr.status>=200 && xhr.status<300) || xhr.status==304) { 53 fnSuccess(xhr.responseText); 54 }else{ 55 fnFaild(xhr.responseText); 56 } 57 } 58 }; 59 } 60 61 62 63 //表單序列化函數 64 function serialize(form){ 65 var parts=[], 66 field=null, 67 i, 68 len, 69 j, 70 optLen, 71 option, 72 optValue; 73 for (i = 0; i < form.elements.length; i++) { 74 field=form.elements[i]; 75 switch (field.type) { 76 case 'select-one': 77 case 'select-multiple': 78 if(field.name.length){ 79 for (var j = 0; j < field.options.length; j++) { 80 option=field.options[j]; 81 if (option.selected) { 82 optValue=""; 83 if (option.hasAttribute) { 84 optValue=(option.hasAttribute('value') ? option.value : option.text); 85 }else{ 86 optValue=(option.attribute['value'].specified ? option.value : option.text); 87 } 88 parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue)); 89 } 90 } 91 } 92 break; 93 case undefined: //字段集 94 case "file": //文本輸入 95 case "submit": //提交按鈕 96 case "reset": //重置按鈕 97 case "button": //自定義按鈕 98 break; 99 case "radio": //單選按鈕 100 case "checkbox": //復選框 101 if (!field.checked) { 102 break; 103 } 104 //執行默認操作 105 default: 106 //不包含沒有名字的表單字段 107 if(field.name.length){ 108 parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value)); 109 } 110 } 111 } 112 return parts.join("&"); 113 } 114 115 </script> 116 </body> 117 </html>