這個筆記是我學習js犀牛書和一個師姐的慕課網(wǎng)學習筆記和js高級編程三個東西的總結(jié)
1骇径,基本概念
超文本傳輸協(xié)議(HyperText Transfer Protocol,HTTP)規(guī)定web瀏覽器如何從web服務器獲取文檔和向服務器提交表單內(nèi)容,以及web瀏覽器如何從Web服務器獲取文檔和向Web服務器提交表單內(nèi)容者春,以及Web如何響應這些請求和提交破衔。
雖然HTTP不在腳本控制下,只是當用戶單擊鏈接钱烟,提交表單和輸入url的時候才發(fā)生晰筛,但js代碼操縱HTTP是可行,但發(fā)生以上請求的時候拴袭,會初始化HTTP請求读第。在這兩種情況下,瀏覽器都會重新加載頁面拥刻,顯然這樣體驗效果不好
AJAX(Asynchronous Javascript and XML)應運而生卦方。這是一種使用腳本操縱HTTP的Web應用架構(gòu),而且不會導致頁面重載泰佳。
而又有一種東西Comet出來了盼砍。它和Ajax一樣也只是使用腳本操縱HTTP的Web應用架構(gòu).但他和Ajax相反。對于Ajax逝她,是客戶端從服務端拉數(shù)據(jù)浇坐。在Comet中,是服務端向客戶端“推”數(shù)據(jù)
<template>標簽也要登場黔宛。此時因為<im g>元素無法實現(xiàn)完整的Ajax傳輸協(xié)議.近刘,通過設置src屬性的url然后發(fā)起請求。此時臀晃,JSON也登場了
實現(xiàn)Ajax技術更簡單的實現(xiàn)方式觉渴,是XMLHttpRequest對象。這是一種用腳本操縱Http的api徽惋。這個API包含了get請求和post請求的能力案淋,同時能用文本或者document對象的形式返回服務器響應。而且不局限XML格式险绘。
2踢京,使用XMLHttpRequest
2.1 新建對象
第一步是要先
var request = new XMLHttpRequest();
//注意,ie6下有不一樣的地方
2.2 指定請求
request.open("get","data.json")
GET請求:用于常規(guī)請求宦棺,適用于當url完全指定請求資源瓣距,且請求對服務器沒有任何副作用(下面講述什么叫副作用)以及當服務器的響應是可緩存的
POST請求:常用于HTML表單。在請求主題中包含表單數(shù)據(jù)且這些數(shù)據(jù)場存儲到服務器的后臺數(shù)據(jù)中( 副作用)
2.3(可選)請求頭
request.setRequestHeader("content-Type","text/plain");
- 如果請求頭多次代咸,新值不會取代之前的值蹈丸,相反,HTTP請求還將包含這個頭的多個副本或這個頭指定的多個值
2.4 向服務器發(fā)送
request.send(null);
- get請求沒有主體,傳遞null或省略逻杖。post常擁有主體慨默,同時應該匹配使用setREquestHeader()指定的"content-type"的頭
3,取得響應
- 異步使用后弧腥,send之后要得到返回相應厦取,后面才能繼續(xù)走。所以必須監(jiān)聽XMLHttpRequest對象上的readystatechange事件管搪。監(jiān)控這個事件虾攻,又必須使用readystate屬性
值 | 含義 |
---|---|
0 | open()尚未調(diào)用 |
1 | open()已調(diào)用 |
2 | 接收到頭信息 |
3 | 接收到相應主體 |
4 | 相應完成 |
- 每次readystate的值改變,會觸發(fā)一次readystatechange事件
*當知道send完成了更鲁,就要檢測傳回來的東西的狀態(tài)霎箍,這時候就要一個status和statusText屬性以數(shù)字和文本的形式返回狀態(tài)碼
附上一個完整的代碼演示
function ajax(url, fnSucc, fnFaild)
{
//1.創(chuàng)建Ajax對象
var oAjax=null;
if(window.XMLHttpRequest)
{
oAjax=new XMLHttpRequest();
}
else
{
oAjax=new ActiveXObject("Microsoft.XMLHTTP");
}
//2.連接服務器
oAjax.open('GET', url, true);
//3.發(fā)送請求
oAjax.send();
//4.接收服務器的返回
oAjax.onreadystatechange=function ()
{
if(oAjax.readyState==4) //完成
{
if(oAjax.status==200) //成功
{
fnSucc(oAjax.responseText);
}
else
{
if(fnFaild)
fnFaild(oAjax.status);
}
}
};
}
3.1 同步相應
把false作為第三個參數(shù)傳遞給open(),那么send()方法將會阻塞到完成請求澡为。所以同步相應下就不需要使用事件處理程序漂坏。僅僅需要檢查status和responseText屬性會可以了
3.2與后臺交互數(shù)據(jù)實例
客戶端代碼之search
document.getElementById("search").onclick=function(){
var request=new XMLHttpRequest();
request.open("GET","server.php? number="+document.getElementById("keyword").value); request.send();
request.onreadystatechange=function () {
if(request.readyState==4){
if(request.status===200){
var data=JSON.parse(request.responseText);//解析服務器返回的信息;
if(data.success){
document.getElementById("searchResult").innerHTML=data.msg; }
else { document.getElementById("searchResult").innerHTML="出現(xiàn)錯誤:"+data.msg; } }
else{ alert("發(fā)生錯誤"+request.status); }
}
}
}
- 使用JSON.parse():
var jsondata='{"staff":[{"name":"洪七","age":70},{"name":"郭靖","age":35},{"name":"黃蓉","age":30}]}';
var jsonobj=JSON.parse(jsondata);
alert(jsonobj.staff[0].name);
結(jié)果:彈出 “洪七”; - Tip:在代碼中使用eval是很危險的!特別是用它執(zhí)行第三方的json數(shù)據(jù)(其中可能包含惡意代碼)時,盡可能使用JSON.parse()方法解析字符串本身方法還可以捕捉json中的語法錯誤.Eg:
客戶端代碼之保存
document.getElementById("save").onclick=function(){
console.log('haha');
var add_staff=new XMLHttpRequest();
add_staff.open("POST","server.php");
var data="number="+document.getElementById("staffnumber").value+"&name="+document.getElementById("staffname").value+"&sex="+document.getElementById("staffsex").value+"&job="+document.getElementById("staffjob").value;
add_staff.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); add_staff.send(data);
add_staff.onreadystatechange=function () {
if(add_staff.readyState==4){
if(add_staff.status===200){
var data=JSON.parse(add_staff.responseText);
if(data.success){
document.getElementById("createResult").innerHTML=data.msg;
}
else {
document.getElementById("createResult").innerHTML = "出現(xiàn)錯誤" + data.msg;
}
}
else{ alert("發(fā)生錯誤"+add_staff.status); }
}
} }
3.3,表單數(shù)據(jù)的請求頭
默認情況下媒至,html表單通過post方法發(fā)送給服務器顶别,而編碼后的表單數(shù)據(jù)用做請求主體。
- 編碼像這樣:
find-pizza&zipcode=032223&radius=1km
響應的頭要這樣:
Content-Type設置為application/x-www-form-urlencoded
這樣就能正確解碼 - json
如果是json拒啰,響應頭要改成application/json