1、Ajax的封裝
function ajax(type,url,param,sync,datetype,callback){//第一個參數是獲取數據的類型,第二個參數是傳入open的url,第三個是用來操作post和get的參數,
//第四個參數是同步或異步,第五個是后台傳過來的數據類型,第六個是對界面進行操作的函數 var xml=''; if(window.XMLHttpRequest){//這四行代碼是用來兼容iE6的 xml=new XMLHttpRequest; }else{ xml=ActiveXObject("Microsoft.XMLHttp"); } if(type=='get'){//如果獲取數據的方式為get則這個參數直接加到傳入的url后面 if(param&¶m!=""){ url+="?"+param; } } xml.open(type,url,sync);//Ajax的第二個階段 if(type=="get"){//如果獲取數據的方式是get則發送空 send(null); }else{ xml.setRequestHeader("Content-type","application/x-www-form-urlencode");//這兩行代碼是post的發送方式 send(param); } if(sync==true){//如果是異步的情況 xml.onreadystatechange=function(){//這是Ajax里面的回調函數 if(xml.readystate==4){ if(xml.status==400){ var result=""; if(datetype=="json"){//如果傳入數據的類型是json result=xml.Responsetext; result=JSON.parse(result); }else if(datetype=='XML'){//如果傳入數據的類型是xml result=xml.ResponseXML; }else{//如果傳入的是普通數據 result=xml.Responsetext; } } } if(callback){//確定用戶是否傳入callback這個參數 callback(result);//這是對ajax解析的數據進行操作的函數 } } }else{//如果是同步的話,ajax的回調函數就不能用,直接把回調函數的里面的代碼放在后面就行。 if(xml.readystate==4){ if(xml.status==400){ var result=""; if(datetype=="json"){//如果傳入數據的類型是json result=xml.Responsetext; result=JSON.parse(result); }else if(datetype=='XML'){//如果傳入數據的類型是xml result=xml.ResponseXML; }else{//如果傳入的是普通數據 result=xml.Responsetext; } } } if(callback){//確定用戶是否傳入callback這個參數 callback(result);//這是對ajax解析的數據進行操作的函數 } } }
思考:這個封裝函數還有什么缺點?
如何解決?
obj={//這個是用戶傳入的參數對象 type:'get', datetype:'XML', url:'validate,php', sync:true, param:'usename='+usename } function ajax(obj){ defaults={//這是那個默認的對象 type:'get',//下面這幾個都是比較常用的屬性 datetype:'json', url:'#', sync:true } //仔細看下面這行代碼的意思,是obj中的屬性覆蓋到defaults中去。 //1、如果一些屬性只存在obj中,則會給defaults中增加屬性。 //2、如果obj的一些屬性和defaults中的一些屬性相同則obj會覆蓋defaults中的,但是實際這些屬性還是沒變。 //3、如果defaults中的屬性存在而obj中不存在,則默認會保留哪些預定義屬性 for(var key in obj){ defaults[key]=obj[key]; } }
最終的封裝方案:
function my_ajax(obj){//用戶傳入的對象 var defaults={//函數內默認的對象 type:'get', url:'#', data:{}, success:function(data){} };
for(var key in obj){//遍歷用戶的對象和默認對象相結合 defaults[key]=obj[key]; } var params='';//定義屬性主要是為了給url后面加入要傳遞的參數 for(var attr in defaults.data){//遍歷用戶傳入的參數加到url后面 params+=attr+'='+defaults.data[attr]+"&"; } if(params){ params=params.substring(0,params.length-1);//因為會多一個&,所以這行代碼是為了去除這個&符號; defaults.url=defaults.url+"?"+params; } var script=document.createElement('script'); script.src=defaults.url+"&callback=foo";//傳入回調的函數名稱 window['foo']=function(data){//定義這個函數名稱的函數 defaults.success(data);//用戶傳入的函數 } var head=document.getElementsByTagName('head')[0]; head.appendChild(script); }
2、JQuery里面的ajax
其實實際情況種很少用到自己封裝的ajax函數,一般都是直接引用jquery里面封裝的ajax()方法。
ajax()方法里面的參數有很多,我這里就不一一列舉出來了,就拿一些比較常用的參數來說:
1、data
類型:String
發送到服務器的數據。將自動轉換為請求字符串格式。GET 請求中將附加在 URL 后。查看 processData 選項說明以禁止此自動轉換。必須為 Key/Value 格式。如果為數組,jQuery 將自動為不同值對應同一個名稱。如 {foo:["bar1", "bar2"]} 轉換為 '&foo=bar1&foo=bar2'。
2、dataType
類型:String
預期服務器返回的數據類型。如果不指定,jQuery 將自動根據 HTTP 包 MIME 信息來智能判斷,比如 XML MIME 類型就被識別為 XML。在 1.4 中,JSON 就會生成一個 JavaScript 對象,而 script 則會執行這個腳本。隨后服務器端返回的數據會根據這個值解析后,傳遞給回調函數。可用值:
- "xml": 返回 XML 文檔,可用 jQuery 處理。
- "html": 返回純文本 HTML 信息;包含的 script 標簽會在插入 dom 時執行。
- "script": 返回純文本 JavaScript 代碼。不會自動緩存結果。除非設置了 "cache" 參數。注意:在遠程請求時(不在同一個域下),所有 POST 請求都將轉為 GET 請求。(因為將使用 DOM 的 script標簽來加載)
- "json": 返回 JSON 數據 。
- "jsonp": JSONP 格式。使用 JSONP 形式調用函數時,如 "myurl?callback=?" jQuery 將自動替換 ? 為正確的函數名,以執行回調函數。
- "text": 返回純文本字符串
3、jsonp
類型:String
在一個 jsonp 請求中重寫回調函數的名字。這個值用來替代在 "callback=?" 這種 GET 或 POST 請求中 URL 參數里的 "callback" 部分,比如 {jsonp:'onJsonPLoad'} 會導致將 "onJsonPLoad=?" 傳給服務器。
4、jsonpCallback
類型:String
為 jsonp 請求指定一個回調函數名。這個值將用來取代 jQuery 自動生成的隨機函數名。這主要用來讓 jQuery 生成度獨特的函數名,這樣管理請求更容易,也能方便地提供回調函數和錯誤處理。你也可以在想讓瀏覽器緩存 GET 請求的時候,指定這個回調函數名。
5、success
類型:Function
請求成功后的回調函數。
參數:由服務器返回,並根據 dataType 參數進行處理后的數據;描述狀態的字符串。
這是一個 Ajax 事件。
6、type
類型:String
默認值: "GET")。請求方式 ("POST" 或 "GET"), 默認為 "GET"。注意:其它 HTTP 請求方法,如 PUT 和 DELETE 也可以使用,但僅部分瀏覽器支持。
7、url
類型:String
默認值: 當前頁地址。發送請求的地址。
以下用一個實際的例子來展現ajax的強大
實現查詢天氣預報:
1、先創建一個html頁面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <style>
#div{ text-align: center; margin: 0 auto; } table{ /* border:1px solid red; */ margin: 0 auto; width: 600px; /* height: 1000px; */ border-collapse: collapse; display: none; } table tr,th{ width: 600px; height: 30px; } table td{ background:rgb(173, 204, 233); } table th{ background:rgb(55, 146, 231); } table tr ,td,th{ border: 1px solid rgb(21, 123, 219); } </style> </head> <body> <div id='div'> <h2>天氣預報</h2> <p> <b>請輸入要查詢的城市:</b><input type='text' name='city' id='city'> <input type="button" id='btn' value="查詢"> </p> <table id="tab"> </table> </div> <script> $(function(){ $("#btn").click(function(){ var value=$("#city").val();//獲取用戶輸入input標簽里要查詢的城市名稱 $.ajax({ url: "./weather.php",//url地址指向 data:{//用戶傳入的數據 city:value }, dataType:'json',//數據類型為json success:function(data){//請求成功后的函數 var weather=data.result[0].future; var length=weather.length; var a="<tr ><th>時間</th><th>星期</th><th>白天</th><th>晚上</th><th>氣溫</th><th>風向</th></tr>"; for(var i=0;i<length;i++){ a+="<tr><td>"+weather[i].date+"</td><td>"+weather[i].week+"</td><td>"+weather[i].dayTime+"</td><td>"+weather[i].night+"</td><td>"+weather[i].temperature+"</td><td>"+weather[i].wind+"</td> </tr>"; } document.getElementById('tab').innerHTML=a; tab.style.display="block"; } }) }); }); </script> </body> </html>
2、創建url地址指向的php文件
<?php
//這個php文件是為了跨域從別的網站獲取天氣信息 header('Content-type:text/plain;charset=utf-8'); $ci=curl_init();//初始化 $city=$_GET['city'];//接受從ajax()函數里date里面傳來的數據 $url="http://apicloud.mob.com/v1/weather/query?key=28ababecc964b&city=".urlencode("$city");//這個url是獲取天氣數據的一個接口 curl_setopt($ci,CURLOPT_URL,$url);//設置選項 curl_setopt($ci,CURLOPT_RETURNTRANSFER,1);//設置為將獲取到的內容不顯示在頁面上 $data=curl_exec($ci);//執行curl echo $data;//輸出內容
最終實現的效果圖: