條理清晰的Ajax基礎講解

最近一直在搞基礎的東西,弄了一個持續更新的github筆記,能夠去看看,誠意之做(原本就是寫給本身看的……)連接地址:Front-End-Basics php

此篇文章的地址:Ajax基礎相關 html

基礎筆記的github地址:https://github.com/qiqihaobenben/Front-End-Basics ,能夠watch,也能夠star。html5


正文開始……


Ajax

Asynchronous JavaScript and XML : 異步的js和XML,先後端數據交互的一種技術。git

Ajax優勢

傳輸獲取數據 , 不用跳轉頁面,在本頁面請求服務器,作到實時驗證。
減小用戶返工率而且優化用戶體驗。github

方式

GET方式

把數據放在url中發送,以獲取數據爲主ajax

步驟

一、建立一個ajax對象後端

var ajax = new XMLHttpRequest();

二、傳入請求參數瀏覽器

//method,url,true    參數
ajax.open('get','php/get.php?user='+encodeURIComponent(value),true);

三、發送數據緩存

ajax.send(null);

send()方法傳入一個參數,即要做爲請求主體發送的數據。若是不須要經過請求主體發送數據,則必須傳入null,由於這個參數對有些瀏覽器來講是必需的。安全

注意點

一、用get方式請求,是有長度限制的。由於是經過地址欄的查詢信息來請求的。(即get經過url地址傳輸,post經過瀏覽器內部傳輸)

二、請求信息在地址欄中顯示,直接暴露了用戶填寫的信息,而且訪問的數據會被瀏覽器緩存到歷史記錄中,因此說不安全。

三、在get拼接數據的時候要用encodeURIComponent來包一下,否則在IE低版本瀏覽器中使用中文會亂碼的。

encodeURIComponent('劉')  轉成url
decodeURIComponent('%E5%88%98')  轉成中文

四、有緩存問題 解決方法:在url?後面鏈接一個隨機數,時間戳

POST方式

數據放在 send() 中發送

步驟

一、建立一個ajax對象

var ajax = new XMLHttpRequest();

二、傳入請求參數

ajax.open('post','php/post.php',true);
//method,url,true三個參數的含義
一、提交方式 Form-method 
二、提交地址 Form-action 
三、異步(同步)
異步:非阻塞 前面的代碼不會影響後面代碼的執行
同步:阻塞 前面的代碼會影響後面代碼的執行

三、設置請求頭

ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded')

// 要成功的發送請求頭部信息,必須在調用open() 方法以後且調用send()方法以前調用setRequestHeader()

四、發送數據

ajax.send('user=cfangxu')

注意點

  1. 用post方式請求,理論上來講是沒有長度或體積限制的,看具體瀏覽器和後端的設置。
  2. 數據是經過http正文(請求體-請求正文)進行發送的,不會直接的暴露用戶的信息,而且發送的數據不會被瀏覽器緩存,相對來講是比較安全的。
  3. 在send()的前面須要設置一個請求頭(不設置要出錯)。
post提交的數據格式有多種

    text/plain
    application/x-www-form-urlencoded - 默認
    multipart/form-data

在post提交數據的時候,須要設置請求頭content-type:值能夠爲上面三中類型之一

ajax.setRequestHeader( 'Content-Type','application/x-www-form-urlencoded');
  1. open的時候,不用像get那樣去拼數據,拼接數據是在send中填寫。

接收數據

onload 事件

屬於html5的,有兼容性問題

ajax.onload = function () {
    //打印傳輸過來的數據
    console.log(ajax.responseText)
}

onreadystatechange 事件

支持IE6,兼容性好。

其中的readyState屬性:請求狀態 
0  (未初始化)尚未調用open()方法0是監聽不到的
1  啓動,open() 方法已經被調用。
2  發送,send() 方法已經被調用,但還沒有接收到響應。 
3  接收,已經接收到部分相應數據。 
4  完成,已經接收到所有響應數據,並且能夠在客戶端使用了。

readyState : ajax工做狀態
onreadystatechange : 當readyState改變的時候觸發
status : 服務器狀態,http狀態碼
responseText : 返回以文本形式存放的內容 ajax請求返回的內容就被存放到這個屬性下面

注意

  • 事件監聽最好寫在事件發生以前(即.onload(.onreadystatechange)要放在.send以前),避免沒有監聽到。

擴展

XMLHttpRequest 兼容性問題,單純瞭解,能夠直接略過

new XMLHttpRequest() ie6 及如下不支持,因此須要用到插件
new ActiveXObject('MSXML2.XMLHTTP')
IE中會有三種不一樣的XHR版本: MSXML2.XMLHTTPMSXML2.XMLHTTP.3.0MSXML2.XMLHTTP.6.0 由於只作瞭解,這裏用最老的那一版

兼容寫法以下:
var xhr = null;
if (window.XMLHttpRequest) {    
   //直接用XMLHttpRequest是不能作判斷的,由於IE6下沒有,window.XMLHttpRequest會返回undefined
   xhr = new XMLHttpRequest();
} else {
   xhr = new ActiveXObject('MSXML2.XMLHTTP');
}

也能夠用try catch來解決。
try {
   xhr = new XMLHttpRequest();
} catch (e) {
   xhr = new ActiveXObject('MSXML2.XMLHTTP');
}

表單提交

form 標籤的一些屬性

action : 數據提交的地址,默認是當前頁面

method : 數據提交的方式,默認是get方式
    1.get
    把數據名稱和數據值用=鏈接,若是有多個的話,那麼他會把多個數據組合用&進行鏈接,而後把數據放到url?後面傳到指定頁面
    2.post
    經過請求頭進行請求

enctype : 提交的數據格式,默認application/x-www-form-urlencoded

上傳文件

不論是form仍是ajax,上傳必需要用post請求方式來傳輸。若是後端返回的內容有中文編碼格式,那麼直接輸入到頁面中就能變成中文了。

form

<form action="post_file.php" method="post" enctype="multipart/form-data">
           <input type="file" name="file" id="f" value="" />
           <input type="submit" value="上傳"/>
</form>
action會跳轉頁面

ajax

var ajax = new XMLHttpRequest();

ajax.open('post','post_file.php',true);

//傳輸類型設置爲二進制的格式
ajax.setRequestHeader('Content-Type','multipart/form-data');

//二進制傳輸在寫入send前要用FormData轉換
var fromD = new FormData();    

//FormData構造函數中有一個append方法
//在file中,有一個對象:files(詳細信息的列表)files[0]裏面是files的具體參數;
fromD.append('file',f.files[0]);    

ajax.send(fromD)


ajax的上傳方式須要注意如下幾點:
1.new FormData()

2.給這個對象append(key,value)
key:跟後端的要求走
value:file元素的files[0];

3.send(這個對象)

XMLHttpRequest 2級

FormData

上面的ajax上傳文件用到的 FormData 類型就是 XMLHttpRequest 2級中定義的。

FormData 爲序列化表單以及建立與表單格式相同的數據(用於XHR傳輸)提供了便利。

var data = new FormData();
data.append('name','cfangxu');

append()方法接收兩個參數:鍵和值,分別對應表單字段的名字和字段中包含的值。能夠像上面代碼同樣添加任意多個值。

FormData 構造函數能夠直接傳入表單元素,表單元素的數據預先向其中填入鍵值對。

var data = new FormData(document.forms[0]);

FormData的另外一個方便之處在於用其發送POST請求能夠沒必要明確地在XHR對象上設置請求頭部,XHR對象可以識別傳入的數據類型是FormData的實例,並配置適當的頭部信息。

overrideMimeType() 方法

重寫XHR響應的MIME類型,好比服務器返回的MIME類型是 text/plain,可是數據中實際包含的是XML。根據MIME類型,即便數據是XML, responseXML屬性中仍然是null,經過調用 overrideMimeType()方法,能夠保證把響應當作XML而並不是文原本處理。

var xhr = new XMLHttpRequest();
xhr.open('get','text.php',true);
xhr.overrideMimeType('text/xml');
xhr.send(null);

load 事件

上面提到過,用load事件替代readystatechange,響應接收完畢後會觸發load事件,因此也就沒有必要去檢查readyState屬性了,不過只要瀏覽器接收到服務器的響應,無論狀態如何,都會觸發load事件。因此必需要檢查status屬性,才能肯定數據是否真的是可用的。

var xhr = new XMLHttpRequest();
xhr.onload = function () {
    if(xhr.status >= 200 && xhr.status < 300) {
        console.log(xhr.responseText);
    }else {
        console.log('Request is unsuccessful' + xhr.status)
    }
}
xhr.open('get','test.php',true);
xhr.send(null);

progress 事件

這個事件會在瀏覽器接收新數據期間週期性地觸發。事件監聽函數會接收到一個event對象,其target屬性是XHR對象,可是包含着三個額外的屬性:lengthComputable、position和totalSize。

  • lengthComputable: 是一個表示進度信息是否可用的布爾值。
  • position: 表示已經接收的字節數
  • totalSize: 表示根據Content-Length響應頭部肯定的預期字節數。

這些信息能夠用來展現進度。

var xhr = new XMLHttpRequest();
xhr.onload = function () {
    if(xhr.status >= 200 && xhr.status < 300) {
        console.log(xhr.responseText);
    }else {
        console.log('Request is unsuccessful' + xhr.status)
    }
}
xhr.onprogress = function (event) {
    var showEle = document.getElementById('status');
    if(event.lengthComputable){
        showEle.innerHTML = '接收' + event.position + 'of' + event.totalSize + '字節';
    }
}
xhr.open('get','test.php',true);
xhr.send(null);

爲確保正常執行,必須在調用open()方法以前添加onprogress事件監聽函數。

總結

XMLHttpRequest實例的屬性

readyState
responseType
responseText
responseXML
status
statusText
withCredentials

XMLHttpRequest實例的方法

abort() abort方法用來終止已經發出的HTTP請求。
getAllResponseHeaders()
getResponseHeader()
open()
send()
setRequestHeader()
overrideMimeType()

XMLHttpRequest實例的事件

readyStateChange事件 progress事件 load事件

相關文章
相關標籤/搜索