javascript
[ JS 进阶 ] Ajax 详解 (2) :XHR 实例 GET 和 POST 异步和同步
上一篇文章 我們大概知道了XHR對象是什么東東,也都了解了它的一些屬性和方法,那么現在具體來實現一下Ajax技術 和 了解下XHR2對象。
1.實現Ajax
先來創建個XHR對象的實例:
var xhr = function(){if (window.XMLHttpRequest) {return new XMLHttpRequest();}else{return new ActiveObject('Micrsorf.XMLHttp');} }(); console.log(xhr.readyState);先來看個get請求
xhr.onreadystatechange = function(){switch(xhr.readyState){case 0 : console.log(0,'未初始化....');break;case 1 : console.log(1,'請求參數已準備,尚未發送請求...');break;case 2 : console.log(2,'已經發送請求,尚未接收響應');break;case 3 : console.log(3,'正在接受部分響應.....');data.innerHTML = xhr.responseText;break;case 4 : console.log(4,'響應全部接受完畢');if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {document.write(xhr.responseText);}else{document.write('error:' + xhr.status);}break;} } xhr.open('get','/products/getProduct?id=1'); xhr.send(null);這里發送了個簡單的get異步請求到我本地的web服務器中,然后我們在控制臺看下輸出:
可以看到剛創建完XHR對象后的readyState為0,當readyState為1,2,3,4,時都觸發了onreadystatechange事件,而 readyState為0沒有觸發,readyState為3時觸發了兩次,為什么這樣呢?
為什么為0時沒有觸發,我們剛創建XHR對象后readyState為0,然后接著執行后面的代碼,直到send()方法之前readyState的值都沒有發生改變,所以在onreadystatechange事件中檢測readyState為0是沒有意義的。
readyState為3是觸發了兩次,其實有些請求不止兩次,看你請求的數據量的大小而定,我們增大接收數據來看看:
這就好了,既然我們能在readystate為3時獲取數據的相關信息,那我們就可以利用這個特性在readystate為3時做一個數據加載進度條變化的效果了,這個講到XHR2對象的時候來試試。
還有一個就是在發送get請求時,get請求的數據會附在URL之后(就是把數據放置在HTTP協議頭中),以?分割URL和傳輸數據,參數之間以&相連,如:'/products/getProduct?id=1'。如果數據是英文字母/數字,原樣發送,如果是空格,轉換為+,如果是中文/其他字符,則直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX為該符號以16進制表示的ASCII。
POST把提交的數據則放置在是HTTP包的包體中。
再來個post請求
1.先來個簡單的表單,注冊一個用戶
2.用Ajax提交數據到服務器
var btn = document.getElementById('add'); btn.onclick = function(){var tel = document.getElementById('tel').value.toString(),pwd = document.getElementById('pwd').value.toString();var data =encodeFormData({tel : tel,pwd : pwd}) ;xhr.onreadystatechange = function(){switch(xhr.readyState){case 0 : console.log(0,'未初始化....');break;case 1 : console.log(1,'請求參數已準備,尚未發送請求...');break;case 2 : console.log(2,'正在添加....');break;case 3 : console.log(3,'已接收數據長度:'+xhr.responseText.length );break;case 4 : console.log(4,'響應全部接受完畢');if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {databox.innerHTML = xhr.responseText;}else{databox.innerHTML = 'error:' + xhr.status;}break;}}xhr.open('post','/member/register');xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')xhr.send(data);};那么post請求需要注意兩個地方:
第一:
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')表單數據編碼格式有一個正式的MIME類型:pplication/x-www-form-urlencoded
當使用post方式提交這種順序表單時,必須設置Content-Type請求頭為這個值來模仿表單數據的提交。
第二:
var data =encodeFormData({tel : tel,pwd : pwd }) ;HTTP POST請求包含一個請求主體,它包含了客戶端發送給服務器的數據,比如:
這里為了簡單直接明文傳輸了。 這個數據比較少和簡單,我們也可以直接修改上面的send()方法發送數據的方式如下:
xhr.send('tel='+tel+'&pwd='+pwd);但是當這個表單數據的比叫多而復雜時,再以這種字符串拼接的方式傳遞的話比較容易出錯,不好維護,所以我們需要封裝一個這樣的方法幫助我們將我們的數據拼接成這樣的格式:
function encodeFormData(data){if(!data) return '';var pairs = [];for(var name in data){if(!data.hasOwnProperty(name)) continue;if(typeof data[name] === 'function') continue;var value = data[name].toString();name = encodeURIComponent(name.replace('%20','+'));value = encodeURIComponent(value.replace('%20','+'));pairs.push(name+'='+value);}return pairs.join('&'); }2.GET 還是 POST
get還是post,其實這和ajax是沒有關系的了,主要還是取決于這兩個請求方式的特點:
通過上面的兩個ajax的實例,我們可以看出get請求和post請求的一些特點:
get請求:
- GET 請求可被緩存
- GET 請求保留在瀏覽器歷史記錄中
- GET 請求可被收藏為書簽
- GET 請求不應在處理敏感數據時使用
- GET 請求有長度限制
- GET 請求只應當用于取回數據
post請求:
- POST 請求不會被緩存
- POST 請求不會保留在瀏覽器歷史記錄中
- POST 不能被收藏為書簽
- POST 請求對數據長度沒有要求
那,有了這個比較,你應該知道什么時候用get什么時候用post了。
3.異步和同步
ajax默認的都是異步的請求,我們上面的兩個實例也是用的異步請求,那沒什么不用同步呢?同步和異步有什么特點?
同步請求:
發送器請求-->等待結果-->操作結果-->繼續還行后面的代碼 ,這是同步請求的大致過程,由于客服端的javascript是單線程的,也就是說我們必須等待結果完全接收完畢之后才能繼續執行后面的代碼,嚴格按照步驟一步一步來,它通常會導致整個瀏覽器的UI阻塞(白屏等),如果連接服務器響應很慢,那么用戶瀏覽器將凍結,用不不能進行其他操作。
如果我們發起一個同步請求,chrome瀏覽器會給你這樣一個警告:Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/. 意思就是同步請求不利于用戶體驗。
異步請求:
發送器請求-->繼續還行后面的代碼-->響應結果接收完畢了-->操作結果,這是同步請求的大致過程。
可以看到,異步請求在發送請求之后沒有等待結果的返回而是繼續執行后面的代碼,也就是說在結果返回之前用戶可以操作其他東西或是看到其他UI,用戶體驗良好。但是有些情況下我們還是得用同步請求。
總結
以上是生活随笔為你收集整理的[ JS 进阶 ] Ajax 详解 (2) :XHR 实例 GET 和 POST 异步和同步的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分享:手机应用存5个严重的信息安全隐患你
- 下一篇: hbase性能优化2