ajax put请求_前端基础面试:手写一个ajax,说说XMLHttpRequest 都有哪些属性?
前言
在 Ajax 出現(xiàn)之前,網(wǎng)頁想要和服務(wù)器通信,最常用的方式是使用 form 表單;用戶提交表單后,瀏覽器就開始跳轉(zhuǎn),服務(wù)器接收表單并處理,然后將新的網(wǎng)頁返回給瀏覽器;整個過程用戶都只有等待,用戶之前的操作狀態(tài)會丟失,并且服務(wù)器返回的新網(wǎng)頁常常和之前網(wǎng)頁的大部分內(nèi)容相同,浪費帶寬;可見,使用表單來進(jìn)行網(wǎng)頁和服務(wù)器的交互,會做很多無謂的工作,浪費資源,用戶體驗還差。
Ajax 是 Asynchronous JavaScript and XML(異步的 JavaScript 與 XML 技術(shù))的縮寫,并不是 JavaScript 的一部分,而是網(wǎng)頁與服務(wù)器通信的一系列技術(shù)的總稱。網(wǎng)頁使用 Ajax 與服務(wù)器通信,可以規(guī)避上述 form 表單存在的問題,頁面不會刷新,用戶不用等待請求的返回,可以繼續(xù)在我們的網(wǎng)頁上“沖浪”。第一個大規(guī)模使用 Ajax 的網(wǎng)頁應(yīng)用是 Gmail,Gmail 的出現(xiàn)讓大家意識到網(wǎng)頁還能這么玩,網(wǎng)頁也能做得像桌面應(yīng)用一樣,打破了大家對網(wǎng)頁應(yīng)用的認(rèn)知,可以說 Ajax 為 web 技術(shù)注入了靈魂。
使用
瀏覽器為我們提供了 XMLHttpRequest 對象(低版本 IE 使用 ActiveXObject 對象),讓我們能夠方便地使用 Ajax。下面我們就用 Ajax 來和服務(wù)器打聲招呼:
var xhr// 實例化一個 XMLHttpRequest 對象if (window.XMLHttpRequest) { xhr = new XMLHttpRequest();} else if (window.ActiveXObject) { // IE 6及以下 xhr = new ActiveXObject("Microsoft.XMLHTTP");}// 綁定 xhr.readyState 改變時調(diào)用的回調(diào)xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { console.log(xhr.responseText) console.log('請求成功') } else { console.log('請求錯誤') } }}// 初始化請求xhr.open('GET', '/api/hello');// 設(shè)置請求頭(可選)xhr.setRequestHeader('Accept', '*/*')// 發(fā)出請求xhr.send();可見,發(fā)送一個最簡單的 Ajax 請求,只需幾步:實例化一個 XMLHttpRequest 對象,綁定 readyState 改變時調(diào)用的回調(diào),最后使用 open、send 方法發(fā)出請求即可。
上面的代碼涉及到 XMLHttpRequest 對象的常用屬性、方法,接下來依次解釋它們的作用。
注:為了方便閱讀,下面用 xhr 指代 XMLHttpRequest
xhr.onreadystatechange
請求發(fā)出后,只要 xhr.readyState 發(fā)生變化,就會調(diào)用通過 xhr.onreadystatechange 綁定的函數(shù)。
xhr.readyState
xhr.readyState 的值代表 xhr 對象所處的狀態(tài),可能的狀態(tài)如下:
就像上面的示例一樣,一般我們在 xhr.onreadystatechange 綁定的函數(shù)中判斷 xhr.readyState 的值,當(dāng)值變?yōu)?的時候,我們再做進(jìn)一步處理。
xhr.status
xhr.status 代表服務(wù)器響應(yīng)的 http 狀態(tài)碼,比如上面的示例中,我們認(rèn)為 xhr.status 等于200的時候,服務(wù)器正常返回了我們想要的內(nèi)容,否則認(rèn)為請求發(fā)生錯誤。
xhr.responseText
xhr.responseText 的值即為服務(wù)器響應(yīng)的內(nèi)容。
xhr.open(method, url, async, user, password)
xhr.open方法,用于初始化請求,可以接受5個參數(shù),后三個參數(shù)都是可選的,通常我們也很少使用
- method:要使用的HTTP方法,比如 GET、POST、PUT、DELETE 等
- url:請求的url
- async(可選):是否發(fā)起異步請求,默認(rèn)值為 true;注意,新版本的瀏覽器已經(jīng)不建議將該值設(shè)置為 false 來發(fā)起同步請求
- user(可選):用戶名,用于認(rèn)證
- password(可選):用戶密碼,用于認(rèn)證
xhr.setRequestHeader(header, value)
xhr.setRequestHeader 用于設(shè)置 http 請求的 header。需要注意的是,該方法只能在調(diào)用 xhr.open 初始化請求后,并且在調(diào)用 xhr.send 發(fā)出請求之前調(diào)用,否則會拋出錯誤。該方法接收兩個參數(shù)
- header: 設(shè)置的 header 頭的名字
- value:設(shè)置的 header 頭的值
xhr.send(content)
xhr.send 方法用于發(fā)出請求。注意,如果發(fā)出的是同步請求,該方法會阻塞 js 的執(zhí)行。xhr.send 接收一個參數(shù)
- content:請求發(fā)送的內(nèi)容。如果是 GET 或 HEAD 請求,應(yīng)當(dāng)不傳這個參數(shù)或者傳null
XMLHttpRequest Level 2
在 HTML5 之前,雖然各家瀏覽器都實現(xiàn)了 XMLHttpRequest 接口,但由于沒有統(tǒng)一的規(guī)范,導(dǎo)致各個瀏覽器的實現(xiàn)或多或少有些差異。HTML5 將 XMLHttpRequest 納入了規(guī)范,并在原來的基礎(chǔ)上做了升級,提出了 XMLHttpRequest Level 2。
XMLHttpRequest Level 2 相較于老版本的 XMLHttpRequest 主要新增了如下內(nèi)容:
- 可以設(shè)置HTTP請求的超時時間
- 可以通過 FormData 發(fā)送表單數(shù)據(jù)
- 可以上傳文件
- 支持跨域請求
- 可以獲取服務(wù)器端的二進(jìn)制數(shù)據(jù)
- 可以獲得數(shù)據(jù)傳輸?shù)倪M(jìn)度信息
設(shè)置HTTP請求的超時時間
xhr.timeout
和 xhr.setRequestHeader 一樣,xhr.timeout的值只能在調(diào)用 xhr.open 之后且在 xhr.send 之前設(shè)置
var xhr = new XMLHttpRequest()xhr.open('GET', '/api/hello')xhr.timeout = 2000 // 超時時間,單位是毫秒xhr.ontimeout = function (e) { // XMLHttpRequest 超時,在此做超時的處理}xhr.send(null)發(fā)送表單數(shù)據(jù)
HTML5 新增了一個 FormData 對象,用于模擬表單。我們可以結(jié)合 FormData 與 xhr 發(fā)送表單數(shù)據(jù)
var xhr = new XMLHttpRequest()// 實例化一個 FormData 對象var formData = new FormData()// 向 FormData 添加數(shù)據(jù)formData.append('username', 'whale')formData.append('age', '18')xhr.open('POST', '/api/form')// 發(fā)送表單數(shù)據(jù)xhr.send(formData)上傳文件
FormData 除了可以添加字符串?dāng)?shù)據(jù),也可以添加 blob、file 類型的數(shù)據(jù),因此可以用于上傳文件。在瀏覽器中,一般是通過文件上傳輸入框來獲取 file 對象,比如:
然后監(jiān)聽 input 的 change 事件,獲取 file 對象:
document.getElementById('upload-file').addEventListener('change', function () { formData.append('uploadFile', this.files[0]) xhr.send(formData)})跨域請求
默認(rèn)情況下,瀏覽器出于安全考慮不允許發(fā)送跨域請求,但有時候向不同域的服務(wù)器發(fā)送請求是必要的。為了標(biāo)準(zhǔn)化跨域請求流程,W3C 提出了跨域資源共享(Cross-origin resource sharing,簡稱 CORS)標(biāo)準(zhǔn),在 CORS 出現(xiàn)之前,通常是使用 JSONP 來取巧地解決跨域問題,但由于 JSONP 存在各種限制,因此在支持 CORS 的瀏覽器中(IE10 以下不支持)還是推薦使用 CORS。
要使用 CORS,默認(rèn)情況下,前端不用修改任何代碼,如果瀏覽器發(fā)現(xiàn) XMLHttpRequest 發(fā)出了跨域請求,會幫我們做相應(yīng)的處理,但服務(wù)器需要返回 Access-Control-Allow-Origin 響應(yīng)頭,指定允許進(jìn)行跨域請求的域。
CORS 請求默認(rèn)是不發(fā)送 Cookie 的,如果想要發(fā)送 cookie,服務(wù)器需要返回 Access-Control-Allow-Credentials: true,并且前端需要設(shè)置 withCredentials 屬性:
xhr.withCredentials = true接收二進(jìn)制數(shù)據(jù)
XMLHttpRequest level 1 只能接收文本數(shù)據(jù),新版本 XMLHttpRequest 添加了接收二進(jìn)制數(shù)據(jù)的能力。要接收二進(jìn)制數(shù)據(jù),一般有兩種方式。
一種是使用 overrideMimeType 方法覆寫服務(wù)器指定的 MIME 類型,從而改變?yōu)g覽器解析數(shù)據(jù)的方式。
xhr.overrideMimeType(mimeType)
- mimeType:要設(shè)置的 MIME 類型
比如:
// 告訴瀏覽器,服務(wù)器響應(yīng)的內(nèi)容是用戶自定義的字符集xhr.overrideMimeType('text/plain; charset=x-user-defined')執(zhí)行上面的代碼后,瀏覽器就會將服務(wù)器返回的二進(jìn)制數(shù)據(jù)當(dāng)成文本處理,我們需要做進(jìn)一步的轉(zhuǎn)換才能拿到真實的數(shù)據(jù):
// 獲取二進(jìn)制數(shù)據(jù)的第 i 位的值var byte = xhr.responseText.charCodeAt(i) & 0xff歡迎關(guān)注
總結(jié)
以上是生活随笔為你收集整理的ajax put请求_前端基础面试:手写一个ajax,说说XMLHttpRequest 都有哪些属性?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【IT之家开箱】OPPO Find X6
- 下一篇: 台式电脑没有蓝牙怎么安装