關于 AJAX

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

  • 使用 XMLHttpRequest 發(fā)請求
  • 服務器返回 XML 格式的字符串
  • JS 解析 XML沛厨,并更新局部頁面

如何發(fā)請求

  1. 用 form 可以發(fā)請求归薛,但是會刷新頁面或新開頁面
<body>
  <form action="xxx" method="post">
    <input type="password" name="password">
    <input type="submit">
  </form>
</body>
  1. 用 a 可以發(fā) get 請求隘击,但是也會刷新頁面或新開頁面
<body>
  <a href="/xxx">click</a>
</body>
  1. 用 img 可以發(fā) get 請求闻牡,但是只能以圖片的形式展示
<body>
  <script>
    var image = document.createElement('img')
    image.src = '/xxx'
    document.body.appendChild(image)
    image.onload = function(){
      console.log('success')
    }
    image.onerror = function(){
      console.log('fail')
    }
  </script>
</body>
  1. 用 link 可以發(fā) get 請求葬馋,但是只能以 CSS卑笨、favicon 的形式展示
<body>
  <script>
    var link = document.createElement('link')
    link.rel = 'stylesheet'
    link.href = '/xxx'
    document.head.appendChild(link)
  </script>
</body>
  1. 用 script 可以發(fā) get 請求较锡,但是只能以腳本的形式運行
<body>
  <script>
    var script = document.createElement('script')
    script.src = '/xxx'
    document.body.appendChild(script)
  </script>
</body>

用 XMLHttpResquest 請求

<script>
  myButton.addEventListener('click',(e)=>{
    let request = new XMLHttpResquest()
    request.onreadystatechange = ()=>{
      if(request.readyState = 4){
        if(request.status >= 200 && request.status <300){
          console.log(request.responseText)
        }else if(request.status >= 400){
          console.log('請求失敗')
        }
      }
    }
    request.open('post','/xxx')
    request.send()
  })
</script>

同源策略和CORS跨域

只有 協(xié)議+端口+域名 一模一樣才允許發(fā) AJAX 請求器腋。
比如: jack.com:8001 網站向 frank.com:8002 發(fā)起 AJAX 請求月杉,
那么需要在 frank.com:8002 的后端添加代碼:
response.serHeader('Access-Control-Allow-Orign','http://frank.com:8001')
才能夠成功刃跛。

...
if(path === '/xxx'){
  response.statusCode = 200
  response.setHeader('Content-Type','text/jason;charest=utf-8')
  response.setHeader('Access-Control-Allow-Orign','http://frank.com:8001')
  response.write(`
    {
      "note"{
        "to": "小方",
        "from": "小谷"苛萎,
        "note": "Hello"
      }
    }
  `)
  response.end()
}esle if(...){
  ...
}
...

JS操作請求與響應

1.請求第一部分
XMLHttpRequest.open() 可以配置請求的方法桨昙,host,路徑腌歉。

2.設置請求第二部分請求頭
XMLHttpRequest.setRequestHeader() 是設置HTTP請求頭部的方法蛙酪。此方法必須在 open()方法和 send()之間調用。如果多次對同一個請求頭賦值翘盖,只會生成一個合并了多個值的請求頭桂塞。
語法:

myReq.setRequestHeader(header, value);

<script>
  myButton.addEventListener('click',(e)=>{
    let request = new XMLHttpResquest()
    request.onreadystatechange = ()=>{
      if(request.readyState = 4){
        if(request.status >= 200 && request.status<300){
          console.log(request.responseText)
        }else if(request.status >= 400){
          console.log('請求失敗')
        }
      }
    }
    request.open('post','/xxx')
    request.setRequestHeader('frank','18')
    request.send()
  })
</script>

可以在開發(fā)者工具看到請求頭為 frank : 18

設置Content-Type:
request.setRequestHeader('Content-Type','x-www-form-urlencoded')

3.設置請求第四部分
XMLHttpRequest.send() 方法接受一個可選的參數(shù),其作為請求主體馍驯;如果請求方法是 GET 或者 HEAD阁危,則應將請求主體設置為 null。

<script>
  myButton.addEventListener('click',(e)=>{
    let request = new XMLHttpResquest()
    request.onreadystatechange = ()=>{
      if(request.readyState = 4){
        if(request.status >= 200 && request.status <300){
          console.log(request.responseText)
        }else if(request.status >= 400){
          console.log('請求失敗')
        }
      }
    }
    request.open('post','/xxx')
    request.send('設置第四部分內容')
  })
</script>

4.獲取請求的響應
XMLHttpRequest.getAllResponseHeaders() 方法返回所有的響應頭汰瘫。
或者XMLHttpRequest.getAllResponseHeaders() 方法返回所有的響應頭狂打。
var myHeader = getResponseHeader(name)
status : 200
statusText: OK
responseText : 響應的第四部分

封裝和使用

window.jQuery.ajax = function(method,url,body,successFn,failFn){
  let request = new XMLHttpResquest()
  request.onreadystatechange = ()=>{
    if(request.readyState = 4){
      if(request.status >= 200 && request.status <300){
        successFn.call(undefined,request.responseText)
      }else if(request.status >= 400){
        failFn.call(undefined,request)
      }
    }
  }
  request.open(method,url)
  request.send(body)  
}

myButton.addEventListener('click',(e)=>{
  winsow.jQuery.ajax(
    'post',
    '/xxx',
    'a=1',
    ()=>{conosle.log(1)},
    ()=>{conosle.log(2)}
  )
})
// 傳入 method url body successFn failFn 的值

做一點優(yōu)化

window.jQuery.ajax = function(options){
  let method = options.method
  let url = options.url
  let body = options.body
  let successFn = options.successFn
  let failFn = options.failFn

  let request = new XMLHttpResquest()
  request.onreadystatechange = ()=>{
    if(request.readyState = 4){
      if(request.status >= 200 && request.status <300){
        successFn.call(undefined,request.responseText)
      }else if(request.status >= 400){
        failFn.call(undefined,request)
      }
    }
  }
  request.open(method,url)
  request.send(body)  
}

myButton.addEventListener('click',(e)=>{
  window.jQuery.ajax({
    method: 'post',
    url: '/xxx',
    body: 'a=1',
    successFn: (x)=>{conosle.log(1)},
    failFn: (x)=>{conosle.log(2)} 
  }) 
})

如果 successFn 需要傳兩個參數(shù)

...
 successFn: (x)=>{
     f1.call(undefined,x)
     f2.call(undefined,x)    
},
...

傳 header

...
headers: {
          'Content-Type':'application/x-www-form-urlencoded',
          'frank': '18'
        }
...

// window.jQuery.ajax 調整
window.jQuery.ajax = function(options){
  let method = options.method
  let url = options.url
  let body = options.body
  let successFn = options.successFn
  let failFn = options.failFn
  let headers = options.headers

  let request = new XMLHttpResquest()
  request.onreadystatechange = ()=>{
    if(request.readyState = 4){
      if(request.status >= 200 && request.status <300){
        successFn.call(undefined,request.responseText)
      }else if(request.status >= 400){
        failFn.call(undefined,request)
      }
    }
  }
  request.open(method,url)
  for(let key in headers){
    let value = headers[key]
    request.setRequestHeader(key,value)
  } // 遍歷 headers 獲取 key 和 value
  request.send(body)  
}

對是否傳兩個參數(shù)做一個判斷

window.jQuery.ajax = function(options){
 // 假如傳了兩個參數(shù),做一個判斷
 let url
 if(arguments.length === 1){
   url = options.url
 }else if(arguments === 2){
   url = argumrnts[0]
   options = argumrnts[1]
 }
 let method = options.method
 let url = options.url
 let body = options.body
 let successFn = options.successFn
 let failFn = options.failFn
 let headers = options.headers

 let request = new XMLHttpResquest()
 request.onreadystatechange = ()=>{
   if(request.readyState = 4){
     if(request.status >= 200 && request.status <300){
       successFn.call(undefined,request.responseText)
     }else if(request.status >= 400){
       failFn.call(undefined,request)
     }
   }
 }
 request.open(method,url)
 for(let key in headers){
   let value = headers[key]
   request.setHeader(key,value)
 }
 request.send(body)  
}

Promise

簡化代碼混弥,

myButton.addEventListener('click',(e)=>{
  window.jQuery.ajax({
    method: 'post',
    url: '/xxx',
  }).then(
  (request.responseText)=>{console.log(request.responseText)},
  (request)=>{console.log(error)}
  )
}) 
// 直接在后面跟 then 趴乡,第一個參數(shù)表示成功后執(zhí)行的函數(shù),第二個參數(shù)表示失敗執(zhí)行的函數(shù)

// 可以繼續(xù)跟 then 再一次對結果進行處理  then中文含義就是 然后
myButton.addEventListener('click',(e)=>{
  window.jQuery.ajax({
    method: 'post',
    url: '/xxx',
  }).then(
  (request.responseText)=>{console.log(request.responseText)},
  (request)=>{console.log(error)}
  )
}).then(
(上一次處理結果)=>{console.log(上一次處理結果)}剑逃,
(request)=>{console.log(error2)}
)
window.jQuery.ajax = function(options){
  return new Promise(function(resolve,reject){
    let url
    if(arguments.length === 1){
      url = options.url
    }else if(arguments === 2){
      url = argumrnts[0]
      options = argumrnts[1]
    }
    let method = options.method
    let url = options.url
    let body = options.body
    let headers = options.headers

    let request = new XMLHttpResquest()
    request.onreadystatechange = ()=>{
      if(request.readyState = 4){
        if(request.status >= 200 && request.status <300){
          resolve.call(undefined,request.responseText)
        }else if(request.status >= 400){
          reject.call(undefined,request)
        }
      }
    }
    request.open(method,url)
    for(let key in headers){
      let value = headers[key]
      request.setHeader(key,value)
    }
    request.send(body)         
  })   
}
// Promise接收一個函數(shù)浙宜,返回一個promise對象,有一個 then 的屬性蛹磺。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末粟瞬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子萤捆,更是在濱河造成了極大的恐慌裙品,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俗或,死亡現(xiàn)場離奇詭異市怎,居然都是意外死亡,警方通過查閱死者的電腦和手機辛慰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門区匠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事驰弄÷樘” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵戚篙,是天一觀的道長五鲫。 經常有香客問我,道長岔擂,這世上最難降的妖魔是什么位喂? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮乱灵,結果婚禮上塑崖,老公的妹妹穿的比我還像新娘。我一直安慰自己阔蛉,他們只是感情好弃舒,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著状原,像睡著了一般聋呢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颠区,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天削锰,我揣著相機與錄音,去河邊找鬼毕莱。 笑死器贩,一個胖子當著我的面吹牛,可吹牛的內容都是我干的朋截。 我是一名探鬼主播蛹稍,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼部服!你這毒婦竟也來了唆姐?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤廓八,失蹤者是張志新(化名)和其女友劉穎奉芦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體剧蹂,經...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡声功,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了宠叼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片先巴。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出筹裕,到底是詐尸還是另有隱情醋闭,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布朝卒,位于F島的核電站,受9級特大地震影響乐埠,放射性物質發(fā)生泄漏抗斤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一丈咐、第九天 我趴在偏房一處隱蔽的房頂上張望瑞眼。 院中可真熱鬧,春花似錦棵逊、人聲如沸伤疙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽徒像。三九已至,卻和暖如春蛙讥,著一層夾襖步出監(jiān)牢的瞬間锯蛀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工次慢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留旁涤,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓迫像,卻偏偏與公主長得像劈愚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子闻妓,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內容

  • Ajax是Asynchronous JavaScript and XML的縮寫菌羽。主要用于頁面無刷新請求數(shù)據(jù)。 Aj...
    晴天小豬L閱讀 295評論 0 0
  • Ajax是什么Ajax(Asynchronous JavaScript + XML)即異步JavaScript +...
    前端開發(fā)小匠閱讀 241評論 0 1
  • 一纷闺、什么是AJAX算凿,為什么要使用Ajax(請談一下你對Ajax的認識) ajax全稱Asynchronous Ja...
    dnaEMx閱讀 410評論 0 2
  • ajax的過程。 1. 創(chuàng)建XMLHttpRequest對象,也就是創(chuàng)建一個異步調用對象 2. 創(chuàng)建一個新的HTT...
    AdonisL閱讀 561評論 0 4
  • Ajax是異步的javascript和xml Ajax的交互使用的是瀏覽器的XMLHttpRequest犁功,通過...
    開心糖果的夏天閱讀 260評論 0 3