關於前端上傳文件全面基礎掃盲貼(一) ----- XMLHttpRequest

系列文章

關於前端上傳文件全面基礎掃盲貼(零)
關於前端上傳文件全面基礎掃盲貼(一) ----- XMLHttpRequest
關於前端上傳文件全面基礎掃盲貼(二) ----- File
關於前端上傳文件全面基礎掃盲貼(三) ----- FormData
關於前端上傳文件全面基礎掃盲貼(四) ----- FileReader
關於前端上傳文件全面基礎掃盲貼(五) ----- H5拖拽事件
關於前端上傳文件全面基礎掃盲貼(六) ----- 圖片上傳,旋轉,重繪,預覽等實戰(附DEMO)前端

XMLHttpRequest 對象(知識點主要來源於XMLHttpRequest)(已經熟悉的人也直接跳過這一章節吧)

XMLHttpRequest 對象用於在後臺與服務器交換數據。您可以:
在不從新加載頁面的狀況下更新網頁
在頁面已加載後從服務器請求/接收數據
在後臺向服務器發送數據
而且全部現代的瀏覽器都支持 XMLHttpRequest 對象。(簡直程序員的夢想ヾ(≧O≦)〃嗷~)程序員

一如既往先看兼容性
圖片描述
由於全部現代瀏覽器 (IE7+、Firefox、Chrome、Safari 以及 Opera) 都內建了 XMLHttpRequest 對象。建立 XMLHttpRequest 對象只須要這樣ajax

var xmlhttp=new XMLHttpRequest();

舊的瀏覽器也有辦法拯救!!!segmentfault

var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); // 括號裏面的是ActiveX插件的名字.

客服端請求

open(string method, string url, boolean asynch, String username, string password):

參數 描述
Method 表示http請求方法,通常使用"GET","POST"
url 表示請求的服務器的地址
asynch 表示是否採用異步方法,true爲異步表示腳本會在 send() 方法以後繼續執行,而不等待來自服務器的響應。false爲同步能夠省去額外的 onreadystatechange 代碼。若是在請求失敗時是否執行其他的代碼可有可無,那麼可使用這個參數
username(能夠不指定) 提供http認證機制須要的用戶名
password(能夠不指定) 提供http認證機制須要的密碼

getRequestHeader(name)

獲取指定的相應頭部信息後端

setRequestHeader(name,value)

自定義HTTP頭部信息。需在open()方法以後和send()以前調用,才能成功發送請求頭部信息。跨域

頭部 描述
Accept 瀏覽器可以處理的媒體類型
Accept-Charset 瀏覽器申明本身接收的字符集
Accept-Encoding 瀏覽器申明本身接收的編碼方法,一般指定壓縮方法,是否支持壓縮,支持什麼壓縮方法(gzipdeflate
Host 客戶端指定要請求的WEB服務器的域名/IP 地址和端口號
Referer 發出請求的頁面的URI
Content-Type 標明發送或者接收的實體的MIME類型
X-Requested-With 非標準HTTP頭,只爲firefox3標註是否爲ajax異步請求,null表示爲同步請求

send(content)

向服務器發出請求,若是採用異步方式,該方法會當即返回。content能夠指定爲null表示不發送數據,其內容能夠是DOM對象,輸入流或字符串。數組

abort()

調用此方法可取消異步請求,調用後,XHR對象中止觸發事件,不容許訪問任何與響應相關的屬性;瀏覽器

服務端響應

onreadystatechange事件

能夠傳遞一個函數的名稱,當 XMLHttpRequest 對象的狀態發生改變時,會觸發此函數。狀態從 0 (uninitialized)4 (complete) 進行變化. 事件使代碼複雜化了。可是這是在沒有獲得服務器響應的狀況下,防止代碼中止的最安全的方法。安全

readyState狀態

表示XMLHttpRequest對象的狀態:服務器

狀態 描述
0 未初始化。對象已建立,未調用open
1 open方法成功調用,但send方法未調用
2 send方法已經調用,還沒有開始接受數據
3 正在接受數據。Http響應頭信息已經接受,但還沒有接收完成
4 完成,即響應數據接受完成

status狀態

表示服務器返回的http狀態碼。200表示「成功」,404表示「未找到」,500表示「服務器內部錯誤」等。
總的來講有幾部分:

狀態 描述
1xx 信息提示
2xx 成功
3xx 重定向
4xx 客戶端錯誤
5xx 服務器錯誤

詳情查閱請狠狠地點擊服務器返回的各類HTTP狀態碼介紹

responseText信息

服務器響應的文本內容.

responseXML對象

服務器響應的XML內容對應的DOM對象.

statusText

服務器返回狀態的文本信息。

responseBody(只有微軟的IE支持)

將響應信息正文以unsigned byte數組形式返回(二進制數據).

responseStream(只有IE的某些版本支持)

以Ado Stream對象(二進制流)的形式返回響應信息.

getResponseHeader(name)

從響應信息中獲取指定的http頭.

getAllResponseHeaders

獲取響應的全部http頭.

overrideMimeType

一般用於重寫服務器響應的MIME類型。
Eg,正常狀況下XMLHttpRequest只接收文本數據,但咱們能夠重寫MIME爲「text/plain; charset=x-user-defined」,以欺騙瀏覽器避免瀏覽器格式化服務器返回的數據,以實現接收二進制數據。

完整例子

下面基本跟來源教程同樣,只是部分寫法有點區別

var xmlhttp;

function loadXMLDoc(url) {
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest()
    } else if (window.ActiveXObject) {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP")
    } else {
        xmlhttp = null;
        alert('Your browser does not support XMLHTTP.');
    }

    if (xmlhttp) {
        xmlhttp.onreadystatechange = state_Change;
        xmlhttp.open('GET', url, true);
        xmlhttp.send(null);
    }

    //post
    /*if(xmlhttp) {
        xmlhttp.onreadystatechange = state_Change;
        xmlhttp.open(''POST'', url);
        xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlhttp.send(null);
    }*/
}

function state_Change() {
    if (xmlhttp.readyState === 4) { // 4 = "loaded"
        if (xmlhttp.status === 200) { // 200 = OK
            // ...our code here...
        } else {
            alert("Problem retrieving XML data");
        }
    }
}

看着挺強大,實際仍是有挺多缺點的,例如:

  • 只支持文本數據的傳送,沒法用來讀取和上傳二進制文件。
  • 傳送和接收數據時,沒有進度信息,只能提示有沒有完成。
  • 受到"同域限制"(Same Origin Policy),只能向同一域名的服務器請求數據。

因而後面就有了新版本.

XMLHttpRequest2 對象

新版本針對之前的缺點升級的新增功能主要有如下:

  • 能夠設置 HTTP 請求的時限。(部分瀏覽器兼容有問題)
  • 可使用 FormData 對象管理表單數據。(後續文章會講到)
  • 下載和上載圖像、視頻和音頻等二進制文件(無需使用插件)。(其實整個系列文章都是圍繞這個需求才得出的)
  • 能夠請求不一樣域名下的數據(跨域請求)。(前提是瀏覽器必須支持這個功能,並且服務器端必須贊成這種"跨域"。前端代碼的寫法與不跨域的請求徹底同樣。)
  • 能夠獲取服務器端的二進制數據。
  • 能夠得到數據傳輸的進度信息:

timeout

設置ajax請求超時時限,過了這個時限,就自動中止 HTTP 請求。

responseType

(默認:「text」)在發送請求前,根據您的數據須要,將xhr.responseType設置爲「text」、「arraybuffer」、「blob」或「document」。(暫時不講)

response: 響應

成功發送請求後,xhr的響應屬性會包含DOMString、ArrayBuffer、Blob 或 Document 形式(具體取決於responseTyp的設置)的請求數據。

progress

傳送數據的時候,用來返回進度信息。它分紅上傳和下載兩種狀況:

  • 上傳的progress事件屬於XMLHttpRequest.upload對象
  • 下載的progress事件屬於XMLHttpRequest對象

裏面有兩個重要屬性分別是

  • total:須要傳輸的總字節,
  • loaded:已經傳輸的字節。

(你們都應該猜到這就是實現進度條的東西了)

ontimeout事件

當ajax超過timeout 時限時觸發的回調函數。

load事件:

傳輸成功完成。

error事件:

傳輸中出現錯誤。

loadstart():

傳輸開始。

loadEnd():

傳輸結束,可是不知道成功仍是失敗。

修改版

還以上面的代碼示例修改一下

var xmlhttp;

function loadXMLDoc(url) {
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest()
    } else if (window.ActiveXObject) {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP")
    } else {
        xmlhttp = null;
        alert('Your browser does not support XMLHTTP.');
    }

    if (xmlhttp) {
        xmlhttp.timeout = 3000;
        xmlhttp.ontimeout = time_Out;
        xmlhttp.onreadystatechange = state_Change;
        xmlhttp.upload.onprogress = load_Change;//未經測試
        xmlhttp.open('GET', url, true);
        xmlhttp.send(null);
    }
}

function time_Out() {
    alert('請求超時!');
}

function state_Change() {
    if (xmlhttp.readyState === 4) { // 4 = "loaded"
        if (xmlhttp.status === 200) { // 200 = OK
            // ...our code here...
        } else {
            alert("Problem retrieving XML data");
        }
    }
}

function load_Change(evt) {
    if (evt.lengthComputable) {
        var percentComplete = Math.round(evt.loaded * 100 / evt.total);
        xx.value = percentComplete;
        xx.style.width = percentComplete + "%";
    }
}

實戰須要後臺代碼配合,詳情查閱請狠狠地點擊關於XMLHttpRequest 對象

load_Change函數寫着未經測試是須要傳送後臺返回數據才能拿到,我暫時沒辦法測試,只是給個思路給大家實現進度條,參考網上其餘文章而後加進去的,有興趣能夠自行搜索,沒興趣就忽略吧,怕誤人子弟就很差了(聽說部分手機不支持),裏面的evt通常是這樣子的
圖片描述
詳情查閱請狠狠地點擊原生js上傳文件 顯示進度條

實話實說,這章看起來內容好少比較簡單,其實你被誤導了,是我寫的簡單了,實際有好多東西都沒寫出來,由於我也還在摸索沒太搞懂,想作出一個完整實例須要後端配合能力,這是硬傷,我還沒到這水平,就是讓你們知道有這麼一個東西,建議你們網上查看其它資料.

相關文章
相關標籤/搜索