說說AJAX(同源策略與CORS跨域)

發(fā)請求

  • 用 form 可以發(fā)請求,但是會刷新頁面或新開頁面
  • 用 a 可以發(fā) get 請求,但是也會刷新頁面或新開頁面
  • 用 img 可以發(fā) get 請求,但是只能以圖片的形式展示
  • 用 link 可以發(fā) get 請求,但是只能以 CSS、favicon 的形式展示
  • 用 script 可以發(fā) get 請求,但是只能以腳本的形式運(yùn)行

有沒有一種方法可以實(shí)現(xiàn)

  1. get ,post, delete ,put都可以
  2. 想用什么形式展示就用什么形式展示

IE5率先引入ActiveX對象(API),使得js可以直接發(fā)起HTTP請求,隨后Chrome,F(xiàn)ireFox跟進(jìn)了,取名為XMLHttpRequest,并納入w3c規(guī)范

XMLHttpRequest 是一個構(gòu)造函數(shù),是window下的一個全局對象,可以new XMLHttpRequest來使用


AphWut.png

AJAX
Jesse James Garrett 講如下技術(shù)取名叫做 AJAX:異步的 JavaScript 和 XML

  • 使用 XMLHttpRequest 發(fā)請求
  • 服務(wù)器返回 XML 格式的字符串 (現(xiàn)在用JSON)
  • JS 解析 XML,并更新局部頁面

對于響應(yīng)來說,我們得到的第四部分始終都是字符串,給瀏覽器響應(yīng)了一個符合html格式的字符串


Ap5Uw6.png

接下來給頁面添加一個按鈕,然后監(jiān)聽這個按鈕,每當(dāng)點(diǎn)擊一下,就發(fā)一個請求,之前JSONP我們用script來發(fā)請求,這次用AJAX試一試
main.js代碼

button.addEventListener('click',()=>{
    let request = new XMLHttpRequest()
    request.open('GET','/xxx')
    request.send()
})

server.js代碼

else if (path === '/xxx') {
        response.statusCode = 200
        response.setHeader('Content-Type', 'text/xml')
        response.write(`
            <note>
                <to>George</to>
                <from>John</from>
                <heading>Reminder</heading>
                <body>Don't forget the meeting!</body>
            </note>  
        `)
        response.end()
    } 

ApoP2Q.png

然后js要把這個響應(yīng)讀取一下,這里先要了解readyState這個屬性,當(dāng)readyState是4的時候,說明請求已經(jīng)把響應(yīng)下載完畢了,也就是請求和響應(yīng)整個過程完成。
readyState從0變到4,時間太短來不及捕捉,我們可以通過onreadystatechange來監(jiān)聽
ApotIK.png

如果readState等于4了,那么再判斷status的值來確認(rèn)請求成功還是失敗

button.addEventListener('click',()=>{
    let request = new XMLHttpRequest()
    request.onreadystatechange = ()=>{
        if(request.readyState === 4){
            console.log('請求和響應(yīng)都完畢了')
            if(request.status >= 200 && request.status <=300){
                console.log('請求成功')
            }else if(request.status >= 400){
                console.log('請求失敗')
            }
        }
    }
    request.open('GET','/xxx')
    request.send()
})

請求和響應(yīng)完成并不代表成功和失敗,狀態(tài)碼代表成功和失敗

ApTrpF.png

如果請求成功了我們就用request.responseText獲取響應(yīng)的內(nèi)容,也就是響應(yīng)的第四部分,我們可以用DOM API來操作他們
Ap7ENV.png

ApbkWT.png

這就是操作xml的方法,這種方法很快就過時了。我們想用一種更簡單的形式表示數(shù)據(jù),道格拉斯發(fā)明JSON,這是一門新的語言。
Apb7X4.png

然后我們通過JSON.parse()方法,把符合JSON語法的字符串轉(zhuǎn)換成JS對象
Apqo5t.png

然后我們就可以通過obj.note.from等拿到里面的內(nèi)容

同源策略:如果不是同一個域名同一個端口同一個協(xié)議,就不能發(fā)送AJAX請求。只有AJAX不允許,form,img,script,link都允許
為什么要有同源策略:form發(fā)請求后頁面會自動刷新,原來的頁面就回收了,沒有辦法拿到新頁面的內(nèi)容。而AJAX可以拿到響應(yīng)的內(nèi)容

突破同源策略就是跨域CORS
CORS可以告訴瀏覽器,我倆一家的不要阻止他

 else if (path === '/xxx') {
        response.statusCode = 200
        response.setHeader('Content-Type', 'text/json;charset=utf-8')
        response.setHeader('Access-Control-Allow-Origin','http://frank.com:8001')  //CORS
        response.write(`
            {
                "note":{
                    "to":"舒克",
                    "from":"貝塔",
                    "heading":"你好",
                    "content":"Hellow"
                }
            }
        `)
        response.end()
    }

這樣JSONP和AJAX都可以實(shí)現(xiàn)跨域了,但是JSONP不能POST
CORS全稱是:Cross-Origin Resource Sharing跨站資源共享

手寫一個AJAX

var request  = new XMLHttpRequest
request.open('GET','http://jack.com:8002/xxx')
request.send()
request.onreadystatechange = ()=>{
  if(request.readyState === 4){
    if(request.status >= 200 && request.status <=300){
      let string = request.responseText
      let obj = window.JSON.parse(string)
    }
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容