1. ajax交互流程:
ajax數(shù)據(jù)交互流程
1娱挨、創(chuàng)建一個ajax對象
2、填寫請求地址
3洋侨、發(fā)送請求
4、等待服務(wù)器響應(yīng)
5倦蚪、接收數(shù)據(jù)
1希坚、創(chuàng)建一個ajax對象
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
2、填寫請求地址 3陵且、發(fā)送請求
xmlhttp.open(method,url,async);
xmlhttp.send();
<pre>method:請求的類型裁僧;GET 或 POST
url:文件在服務(wù)器上的位置
async:true(異步)或 false(同步)</pre>
4、服務(wù)器響應(yīng)
如需獲得來自服務(wù)器的響應(yīng)慕购,請使用 XMLHttpRequest 對象的 responseText 或 responseXML 屬性聊疲。
responseText 獲得字符串形式的響應(yīng)數(shù)據(jù)。
responseXML 獲得 XML 形式的響應(yīng)數(shù)據(jù)沪悲。
如果來自服務(wù)器的響應(yīng)并非 XML获洲,請使用 responseText 屬性。
如果來自服務(wù)器的響應(yīng)是 XML殿如,而且需要作為 XML 對象進行解析贡珊,請使用 responseXML 屬性。
onreadystatechange 事件:
當請求被發(fā)送到服務(wù)器時涉馁,我們需要執(zhí)行一些基于響應(yīng)的任務(wù)飞崖。
每當 readyState 改變時,就會觸發(fā) onreadystatechange 事件谨胞。
readyState 屬性存有 XMLHttpRequest 的狀態(tài)信息固歪。
下面是 XMLHttpRequest 對象的三個重要的屬性:
1、onreadystatechange :存儲函數(shù)(或函數(shù)名)胯努,每當 readyState 屬性改變時牢裳,就會調(diào)用該函數(shù)。
2叶沛、readyState:存有 XMLHttpRequest 的狀態(tài)蒲讯。從 0 到 4 發(fā)生變化。
0: 請求未初始化
1: 服務(wù)器連接已建立
2: 請求已接收
3: 請求處理中
4: 請求已完成灰署,且響應(yīng)已就緒
3判帮、status :
200: "OK" ;404: 未找到頁面
當 readyState 等于 4 且狀態(tài)為 200 時溉箕,表示響應(yīng)已就緒:
<pre>xmlhttp.onreadystatechange=function()
{if (xmlhttp.readyState==4 && xmlhttp.status==200)
{document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}</pre>
<pre><script>
window.onload=function(){
var inputs=document.querySelectorAll("input");
inputs[2].onclick=function(){
var val=inputs[0].value;
//1晦墙、創(chuàng)建一個ajax對象
var ajax=new XMLHttpRequest;
//2、填寫請求地址
ajax.open('get','php/get_json.php?user='+val,true);
//3肴茄、發(fā)送請求
ajax.send();
//4晌畅、等待服務(wù)器響應(yīng)
ajax.onload=function(){
//5、接收數(shù)據(jù)
var span=document.querySelector("span");
//ajax請求過來的數(shù)據(jù)都是字符串寡痰,它不能用對象的操作方法 直接操作
//console.log(typeof ajax.responseText); //string
var result=JSON.parse(ajax.responseText);
//span.innerHTML=ajax.responseText;
if(result.code==0){
alert('可以注冊');
}else{
alert('請換一個');
}
};
};
};
</script>
</head>
<body>
用戶名:<input type="text" name="username" /><span></span>`<br /><br />`
密碼:<input type="password" name="password" />
<input type="button" value="提交" />
</body></pre>
2. get和post的區(qū)別
get方式:
1抗楔、通過地址欄信息進行數(shù)據(jù)傳輸棋凳,傳輸?shù)拇笮∮邢拗?br> 2、不安全连躏,用戶的所有信息都會暴露出來
3剩岳、拼接數(shù)據(jù)的時候要用encodeURI轉(zhuǎn)一下碼,不然有中文就會亂碼
4入热、不用設(shè)置請求頭
5拍棕、數(shù)據(jù)拼接在open方法里
6、會有緩存問題
post方式:
1才顿、通過send向服務(wù)器傳輸數(shù)據(jù),理論上來說是沒有長度或體積限制
2尤蒿、相對來說安全郑气,因為不直接暴露用戶信息
3、不用轉(zhuǎn)碼腰池,已經(jīng)通過請求頭設(shè)置了數(shù)據(jù)格式尾组,不會有亂碼
4、在send()的前面需要設(shè)置一個請求頭(不設(shè)置要出錯)
ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
5示弓、數(shù)據(jù)要拼接在send方法里
6讳侨、沒有緩存問題
<pre><script>
window.onload=function(){
var inputs=document.getElementsByTagName("input");
inputs[2].onclick=function(){
//console.log(decodeURI('%E9%99%88%E5%AD%A6%E8%BE%89'))
var val=inputs[0].value;
//1、創(chuàng)建一個ajax對象
var ajax=null;
if(window.XMLHttpRequest){
ajax=new XMLHttpRequest;
}else{
ajax=new ActiveXObject('Microsoft.XMLHTTP');
}
//2奏属、填寫請求地址
ajax.open('get','php/get.php?user='+encodeURI(val),true);
//ajax.open('post','php/post.php',true);
//post發(fā)送請求的時候一定要在發(fā)送前設(shè)置一下請求頭
//ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//ajax.send('user='+val);
//3跨跨、發(fā)送請求
ajax.send();
//4、等待服務(wù)器響應(yīng)
ajax.onreadystatechange=function(){
//5囱皿、接收數(shù)據(jù)
var span=document.getElementsByTagName("span")[0];
span.innerHTML=ajax.responseText;
};
};
};
</script></pre>
3. onreadystatechange與onload
ajax.readyState AJAX運行步驟:
它的值為4的話說明AJAX已經(jīng)運行完成
0 初始化 還沒有調(diào)用open()方法
1 載入 已調(diào)用send()方法勇婴,正在發(fā)送請求
2 載入完成 send()方法完成,已收到全部響應(yīng)內(nèi)容
3 解析 正在解析響應(yīng)內(nèi)容
4 完成 響應(yīng)內(nèi)容解析完成嘱腥,可以在客戶端調(diào)用了
ajax.status服務(wù)器對請求的反饋(狀態(tài)碼)耕渴,200就是成功的,404就是錯誤的齿兔。
onreadystatechange:
readyState的值發(fā)生改變時觸發(fā)的事件橱脸,只要這個值有變化就會觸發(fā)
onload:
所有請求成功完成后觸發(fā),此時readystate的值為4(IE678不支持)
(新的XMLHttpRequest不推薦用onreadystatechange分苇,使用onload)
4. 封裝ajax
<pre>
url 地址
method 請求方式get/post
dataType 返回什么數(shù)據(jù)類型srging/json/xml data 請求時候的傳的數(shù)據(jù)(它是一個對象) succ 成功后的回調(diào)函數(shù)
fail 失敗后的回調(diào)函數(shù)
function ajax(json){
var settings={
url:'',
method:'get',
data:{},
dataType:'json',
succ:function(){},
fail:function(){}
};
//用戶傳的參數(shù)覆蓋默認參數(shù)
for(var attr in json){
settings[attr]=json[attr];
}
//把數(shù)據(jù)拼成正確的格式
var arr=[];
for(var attr in settings.data){
arr.push(attr+'='+settings.data[attr]);
}
settings.data=arr.join('&');
//聲明一個ajax對象
var ajax=window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');
//設(shè)置請求方式
if(settings.method.toLocaleLowerCase()==='get'){
ajax.open(settings.method,settings.url+'?'+settings.data+'&'+new Date().getTime(),true);
ajax.send();
}else{
ajax.open(settings.method,settings.url,true);
ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
ajax.send(settings.data);
}
//設(shè)置完成事件的兼容性
if(typeof ajax.onload==='undefined'){
ajax.onreadystatechange=ready;
}else{
ajax.onload=ready;
}
function ready(){
if(ajax.readyState==4){
if(ajax.status==200){
switch(settings.dataType.toLocaleLowerCase()){
case 'string':
settings.succ(ajax.responseText);
break;
case 'json':
settings.succ(JSON.parse(ajax.responseText));
break;
case 'xml':
settings.succ(ajax.responseXML);
}
}else{
settings.fail(ajax.status);
}
}
};
}</pre>
5. 跨域
跨域:兩個不同域名下的數(shù)據(jù)進行交互添诉。Ajax之所以不能跨域其實是因為XMLHttpRequest受到同源策略的限制,只能讓它訪問同源下的數(shù)據(jù)医寿,不能訪問不同源下的數(shù)據(jù)
同源策略
每個網(wǎng)站只能讀取同一來源的數(shù)據(jù)吻商,這里的同一來源指的是主機名(域名)、協(xié)議(http/https)和端口號的組合糟红。在沒明確授權(quán)的情況下艾帐,不能讀寫對方的資源乌叶,它是瀏覽器最核心也最基本的安全功能
源:協(xié)議、端口柒爸、域名
只要不同源就跨域
協(xié)議
http 超文本協(xié)議
https HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進行加密傳輸准浴、身份認證的網(wǎng)絡(luò)協(xié)議要比http協(xié)議安全
file 本地協(xié)議
ftp 文件共享協(xié)議
跨域解決辦法
1、在標準瀏覽器下XMLHttpRequest配合后端設(shè)置一個請求權(quán)限
在php里寫上 header('Access-Control-Allow-Origin:*');
這個是XMLHttpRequest 2級支持的捎稚,非標準瀏覽器不支持
2乐横、服務(wù)器代理
服務(wù)器文件可以訪問你想要的資源,而你又能訪問服務(wù)器文件今野,所以你就可以訪問想要的資源
缺點:如果想訪問的資源需求有變葡公,對于后端的開發(fā)成本就很大
3、iframe条霜、flash催什、postMessage、WebSocket
http://www.freebuf.com/articles/web/65468.html
Jsonp:
ajax的核心是通過XmlHttpRequest獲取非本頁內(nèi)容宰睡,
而jsonp的核心則是動態(tài)添加<script>標簽來調(diào)用服務(wù)器提供的js腳本
*帶src屬性的<script> < img > <iframe><link>等標簽是不需要遵守同源策略的蒲凶,但是通過src加載的資源,瀏覽器限制了javascript的權(quán)限拆内,只能讀不能寫
*jsonp(json+padding)
1旋圆、通過script標簽引入某些數(shù)據(jù),是同步模式的麸恍,只有上面的代碼加載完成才能繼續(xù)加載下面的代碼一般在用script標簽做跨域的時候灵巧,不建議將數(shù)據(jù)提前加載,應(yīng)該按需加載
2抹沪、當需要數(shù)據(jù)的時候創(chuàng)建一個script標簽孩等,將需要的數(shù)據(jù)放在src中,通過onload去監(jiān)聽是否請求過來采够,請求完畢就調(diào)用傳回來的數(shù)據(jù)(異步加載)
3肄方、jsonp不能用post請求只能用get方式請求
<pre><!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button>點擊1</button>
<button>點擊2</button>
< ul >< /ul >
< ul >< /ul >
<script>
var buttons=document.querySelectorAll("button");
var uls=document.querySelectorAll("ul");
buttons[0].onclick=function(){
var script=document.createElement("script");
script.src='http://localhost/php/jsonp_callBack.php?callback=fn1&num=number';
document.getElementsByTagName('head')[0].appendChild(script);
};
function fn1(data){
var str='';
for(var i=0;i<data.length;i++){
str+='<li>'+data[i]+'</li>';
}
uls[0].innerHTML=str;
}
buttons[1].onclick=function(){
var script=document.createElement("script");
script.src='http://localhost/php/jsonp_callBack.php?callback=fn2';
document.getElementsByTagName('head')[0].appendChild(script);
};
function fn2(data){
var str='';
for(var i=0;i<data.length;i++){
str+='<li>'+data[i]+'</li>';
}
uls[1].innerHTML=str;
};
</script>
</body>
</html>
</pre>