Ajax實用篇

在介紹ajax之前,博主想先介紹一些關于HTTP協(xié)議的知識.
例如百度的網(wǎng)址: http://www.baidu.com 我們可以看到,在整個域名地址的開頭,有一個http協(xié)議,類似的還有https協(xié)議.

1.什么是Ajax?

Ajax全稱:Asynchronous JavaScript+XML

它不是一個技術,實際上是幾種技術的結合,合在一起就成了一個功能強大的新技術.

主要作用是在無刷新頁面的情況下向服務器讀取數(shù)據(jù),可以應用在用戶登入,在線聊天室等地方

2.編寫一個Ajax

Ajax的核心實際是一個XMLHttpRequest對象,這個對象在目前的所有瀏覽器都支持,只是IE6 和 IE5的寫法不一樣而已驴娃。既然是一個對象的話,就存在它內置的屬性和方法.

1.創(chuàng)建XMLHttpRequest對象

首先,我們要先創(chuàng)建XMLHttpRequest這么一個對象.
出于兼容性考慮,為了照顧IE5,6在這呢,我做了一個兼容性的處理

var  xhr = window.XMLHttpRequest ? XMLHttpRequest( ) : ActiveXObject("Microsoft.XMLHTTP");

XMLHttpRequest對象實際也是屬于window的,所以出于嚴謹并避免不必要的麻煩,還是window.XMLHttpRequest比較好.
XMLHttpRequest()各大瀏覽器都支持
ActiveObject("Microsoft.XMLHTTP")是IE5.6的寫法

2.連接到服務器

當xhr對象創(chuàng)建完畢之后,我們要使用一個open()的方法來連接到服務器
先來看下寫法:

xhr.open('GET', 'msg.txt', true) 

open()方法中有3個參數(shù),我們分別來看下什么意思
第一個參數(shù):
請求方法,一般是get或post
第二個參數(shù):
請求是url
第三個參數(shù):
是否為異步,默認true是異步,false是同步

3.監(jiān)聽請求狀態(tài)

使用onreadystatechange方法,來監(jiān)聽請求狀態(tài).
請求狀態(tài)xhr.readyState的值保存了xhr的狀態(tài)
然而xhr一共有5種狀態(tài),分別是:

  • 0 未初始化鹉胖。對象new出來了肮疗,但是還沒有調用open方法
  • 1 啟動播聪。 已經(jīng)調用open象对,但是還沒有調用send方法
  • 2 發(fā)送削彬。 已經(jīng)send方法乌妙,但是還沒有接收到相應
  • 3 接收。 已經(jīng)開始接收數(shù)據(jù)替蛉,但是還沒有完全接收贯溅。
  • 4 完成。 已經(jīng)完全接收數(shù)據(jù)躲查。
    我們主要監(jiān)聽的的第5種狀態(tài),也就是完全接收數(shù)據(jù)的狀態(tài).
    注:xhr.readyState==4只是表示接收數(shù)據(jù)完成,可以對數(shù)據(jù)進行處理了,此時還得再做一個判斷看看服務器是否響應成功,也就是判斷xhr.status是否為200,200表示成功,304雖然也表示成功,但是有緩存.
xhr.onreadystatechange=function(){
            if(xhr.readyState==4){
                if(xhr.status==200||xhr.status==304){
                    onSuccess(xhr.responseText);
                }else{
                    if(typeof onFail=="function"){
                        onFail(xhr.status);
                    }
                }
            }

xhr.responseText指的是ajax向服務器請求之后返回的請求結果.

4.發(fā)送請求

使用xhr.send()方法來向服務器發(fā)送請求
send()方法內也可以傳遞參數(shù),當使用get請求時,只要傳遞null就行了
(若是使用post請求方式的時候,()內可以傳入一個數(shù)據(jù)參數(shù)data,后面會提到)

xhr.send(null)

通過以上四個步驟,我們已經(jīng)會簡單的使用ajax,但是在實際運用中,不可能要用到ajax的時候就再寫一遍,那樣很沒有效率,所以我們可以將整段ajax代碼封裝到一個js代碼中,在我們每次要用到ajax的時候,只需要調用這段js代碼就可以了.
如下,我將以上的四個步驟封裝到了一個myAjax對象中,這個對象中提供了倆個方法,一個是針對get調用,一個是針對post調用,倆個方法異曲同工,只不過在參數(shù)的使用上有一些的不同.具體代碼如下:
文件名: myAjax.js

var myAjax = {
    /**
     * 負責get請求
     * @param url      url地址
     * @param onSuccess ajax請求成功時候的回調
     * @param onFail    ajax請求失敗時候的回調
     */
    get:function (url,onSuccess,onFail) {
        if(!(typeof onSuccess=="function")) return;
        var xhr = XMLHttpRequest ? new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');
        xhr.open('GET',url);
        xhr.onreadystatechange=function(){
            if(xhr.readyState==4){
                if(xhr.status==200||xhr.status==304){
                    onSuccess(xhr.responseText);
                }else{
                    if(typeof onFail=="function"){
                        onFail(xhr.status);
                    }

                }
            }
        };
        xhr.send(null);
    },

    /**
     * 負責get請求
     * @param url      url地址
     * @param data     請求的數(shù)據(jù)
     * @param onSuccess ajax請求成功時候的回調
     * @param onFail    ajax請求失敗時候的回調
     */
    post:function (url,data,onSuccess,onFail) {
         if(!(typeof onSuccess=="function")) return;
        var xhr = XMLHttpRequest ? new XMLHttpRequest():new ActiveXObject('Microsoft.XMLHTTP');
        xhr.open('POST',url);
        xhr.onreadystatechange=function(){
            if(xhr.readyState==4){
                if(xhr.status==200||xhr.status==304){
                    onSuccess(xhr.responseText);
                }else{
                    if(typeof onFail=="function"){
                        onFail(xhr.status);
                    }
                }
            }
        };
        //在發(fā)送請求之前必須添加這個請求頭,表示表單數(shù)據(jù)進行url編碼
        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        xhr.send(data);
    }
    }
};

這樣當我們要用到ajax對象的時候,引用這段js代碼就ok了.
例:
編寫一個剪短的登入程序,當用戶輸入的用戶名和密碼和后臺設置的一樣,即顯示登入成功.

1.編寫一段php代碼:
文件名:    data.php

<?php
$name = $_POST["name"];
$age = $_POST["pwd"];
header('Content-type:text/html; charset="UTF-8"');
header("Access-Control-Allow-Origin:*");
if($name == "李四"&&$pwd=="123456"){
    echo $name . "登入成功" ;
}else{
    echo $name . "登入失敗";
}
?>

2.HTML代碼

<form action="data2.php" method="post" id="form1" enctype="application/x-www-form-urlencoded">
        <input type="text" name="name">
        <input type="text" name="pwd">
        <input type="submit" value="登錄">
 </form>

3.引入ajax.js并編寫js代碼

<script type="text/javascript" src="myAjax.js"></script>
<script>
    var form1 = document.querySelector('#form1');
    form1.onsubmit=function (e) {
        e.preventDefault();//阻止事件默認行為
        var msg = "name=" + this.name.value+'&age="+this.age.value;
        myAjax.post('data2.php',msg,function (result) {
            console.log(result);
        })
    }
</script>

同源

通過博主上面的描述,相信大家對ajax都有了一定的了解,那么ajax這么牛能夠使Web頁面不用打斷交互流程進行重新加載它浅,就可以動態(tài)地更新,就沒有什么限制嗎?答案是有的,ajax訪問網(wǎng)頁的時候,ajax的地址,必須和當前頁面同源,否則ajax就不能訪問.
那么這里就要介紹一下同源.
在頁面的地址欄里,我們經(jīng)常可以看到我們輸入的地址,都有一些相似之處,簡單來說,一個網(wǎng)頁的地址主要有這樣幾個組成部分:
協(xié)議://域名:端口號/資源路徑?查詢參數(shù)
https://www.baidu.com/s?ie=UTF-8&wd=王
那么只要倆個網(wǎng)址的 協(xié)議 域名 端口號 三個部分相同,這倆個網(wǎng)址就同源.
如:同源
? http://www.baidu.com
? http://www.baidu.com/abc/a.html
? 不同源:
? http://www.baidu.com
? https://www.baidu.com/abc/a.html

不受同源策略的影響有:

1.img標簽加載圖片

2.script標簽加載js文件

打破同源

現(xiàn)在主要是用倆種方式來打破同源,一直是利用jsonp,還有一種是服務器打破同源

1.jsonp

jsonp: json padding的簡稱,實際就是把json數(shù)據(jù)偽造為一個合理的js代碼.
我們在正常讀取json數(shù)據(jù),得通過ajax來從服務器讀取,但對于一些不同源的json數(shù)據(jù),我們就無法正常讀取,所以這時可以采用一個投機取巧的辦法吧,就是把json數(shù)據(jù)偽造為一個合理的js代碼,這樣就能通過調用js代碼來成功讀取json數(shù)據(jù),如看下面的例子:

<script>
function foo(obj){
  console.log(obj)
}
</script>
<script type= "text/script" src= "data.json"></script>


data.json:
foo({
  name:'王先生'
})

將json數(shù)據(jù)用一個foo的函數(shù)封裝起來,只要在要讀取json數(shù)據(jù)的時候將json文件用script標簽來引用,并通過foo函數(shù)調用就可以了.

2.服務器打破同源

就像前面說的,判斷是否同源只要看協(xié)議域名端口號三個地方相同不相同,要是相同的話就是同源,我們的ajax就可以訪問到.那么如果我們將服務器端口設置一下,也就是直接在我們的php文件中修改

在php文件的判斷之前加上:
// *代表的就是所有域名都可以訪問
header("Access-Control-Allow-Origin:*");

encodeURIComponent編碼

其實每個漢字都有對應的URI編碼,window提供了一個全局的方法encodeURIcomponent(),將中文轉換為URI編碼
一個中文由3個%號組成,如:

var name = encodeURIComponent('李四');
console.log(name);
=>%E6%9D%8E%E5%9B%9B

后文

Ajax實際就是通過get或者post方法在js中從php文件或者json文件讀取到數(shù)據(jù),然后在js中對這些數(shù)據(jù)進行操作.在實際的開發(fā)中,我們看到頁面上的很多圖片信息或者產(chǎn)品信息,都是通過Ajax讀取數(shù)據(jù)然后添加到頁面中.
另外,要是有小伙學過JQuery的話,會知道JQuery有它內置的Ajax,我們可以直接利用$.get(url,function(result){ })來讀取數(shù)據(jù).

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末镣煮,一起剝皮案震驚了整個濱河市姐霍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌典唇,老刑警劉巖镊折,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異介衔,居然都是意外死亡恨胚,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門炎咖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赃泡,“玉大人,你說我怎么就攤上這事乘盼∩埽” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵绸栅,是天一觀的道長级野。 經(jīng)常有香客問我,道長粹胯,這世上最難降的妖魔是什么蓖柔? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任辰企,我火速辦了婚禮,結果婚禮上渊抽,老公的妹妹穿的比我還像新娘蟆豫。我一直安慰自己,他們只是感情好懒闷,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著栈幸,像睡著了一般愤估。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上速址,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天玩焰,我揣著相機與錄音,去河邊找鬼芍锚。 笑死昔园,一個胖子當著我的面吹牛,可吹牛的內容都是我干的并炮。 我是一名探鬼主播默刚,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逃魄!你這毒婦竟也來了荤西?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤伍俘,失蹤者是張志新(化名)和其女友劉穎邪锌,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體癌瘾,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡觅丰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了妨退。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妇萄。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖碧注,靈堂內的尸體忽然破棺而出嚣伐,到底是詐尸還是另有隱情,我是刑警寧澤萍丐,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布轩端,位于F島的核電站,受9級特大地震影響逝变,放射性物質發(fā)生泄漏基茵。R本人自食惡果不足惜奋构,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拱层。 院中可真熱鬧弥臼,春花似錦、人聲如沸根灯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烙肺。三九已至纳猪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間桃笙,已是汗流浹背氏堤。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留搏明,地道東北人鼠锈。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像星著,于是被迫代替她去往敵國和親购笆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內容