Ajax知识点整理

1、javascript原生Ajax

1.简介

Ajax是Asynchronous JavaScript+XML(异步JavaScript和XML)的缩写。javascript

该名称诞生于XML仍是数据传输首选格式的时期,如今这种状况已经不复存在。尽管X在Ajax中表明XML, 但因为JSON的许多优点,好比更加轻量以及做为Javascript的一部分,目前 JSON 的使用比XML更加广泛。JSON和XML都被用于在Ajax模型中打包信息。php

Ajax技术的核心是 XMLHttpRequest对象 (简称XHR)。XHR为向服务器发送请求和解析服务器响应提供了流畅的接口。可以以异步方式从服务器取得更多信息,意味着用户单击后,不用刷新页面也能得到新数据。便可以使用XHR对象取得新数据,而后经过DOM将新数据插入到页面中。html

Ajax的好处:java

  1. 能够异步生成请求,用户能够在表单被处理时继续与文档交互。而传统提交表单发送到服务器,用户必须等待服务器处理数据并生成响应。
  2. 响应信息能够仅更新页面的一部分。而传统提交表单到服务器后,整个页面被刷新,全部上下文信息都丢失了。

XMLHttpRequest对象的特色:jquery

  1. XMLHttpRequest对象能够接受任何数据类型而不只仅为XML
  2. 它支持的协议类型包括不限于http(还包括file,ftp)

2.XMLHttpRequest的API

xhr.onreadystatechange

只要xhr.readyState的值改变一次,就会触发一次readystatechange事件。因此能够利用该事件来检测readyState发生变化后的值。es6

readystatechange事件处理程序只能经过xhr.onreadystatechange(DOM0级法法)来绑定才能确保跨浏览器的兼容性,由于并不是全部浏览器都支持DOM2级方法ajax

xhr.readyState

请求/响应过程的当前活动阶段。该属性可能的值为:json

  • 0:未初始化。还没有调用open()方法。
  • 1: 启动。已经调用open(),但还没有调用send()。
  • 2: 发送。已经调用send(),但还没有收到响应。
  • 3: 接收。已经接收到部分响应数据。
  • 4:完成。已经接收到所有响应数据,并且已经能够在客户端使用了。

xhr.status

响应的HTTP状态码。一般是将 200<= 状态码 <300 或 status为304做为响应成功的标志。api

Tips: 304表示请求的资源并无被修改,能够直接使用浏览器缓存中的版本,因此也意味着响应有效。跨域

xhr.statusText

HTTP状态的说明文字。

xhr.responseText

做为响应主体被返回的文本。

xhr.open()

初始化一个请求。

参数:

  • method:请求所使用的HTTP方法; 例如 "GET", "POST", "PUT", "DELETE"等

  • url:该请求要访问的url。能够是绝对地址,也能够是相对于执行代码的当前页面的相对地址。

  • async:布尔值,是否异步发送请求,默认为true

  • user(可选):用户名,为受权使用;默认为空string.

  • password(可选):密码,可选参数,为受权使用;默认为空string.

注意: 调用该方法并不会真正发送请求,只是启动一个请求以备发送。

xhr.send()

发送请求. 若是该请求是异步模式(默认),该方法会马上返回. 相反,若是请求是同步模式,则直到请求的响应彻底接受之后,该方法才会返回.

参数:

  • 请求主体发送的数据。若是不须要请求主体发送数据,如GET请求,那么必须传入null,由于该参数对于有些浏览器是必需的。

xhr.abort()

若是请求已经被发送,则马上终止请求。

调用这个方法后,XHR对象会中止触发事件readystatechange,也再也不容许访问任何与响应有关的对象属性。

xhr.setRequestHeader()

默认会发送的请求头有:

  • Accept:浏览器可以处理的内容类型
  • Accept-Charset:浏览器可以显示的字符集
  • Accept-Encoding:浏览器可以处理的压缩编码
  • Accept-language:浏览器当前设置的语言
  • Connection:浏览器与服务器之间链接的类型(一般为keep-alive,即网络链接就是持久的,使得对同一个服务器的请求能够继续在该链接上完成。)
  • Cookie:当前页面设置的任何cookie
  • Host:发出请求的页面所在的域
  • Referer:发出请求的页面的URI. 即表示当前页面是经过此来源页面里的连接进入的。服务端通常使用 Referer 首部识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等。
  • User-Agent:浏览器用户代理字符串

该方法会设置自定义的请求头部信息。

参数:

  • header: 将要被赋值的请求头名称。
  • value: 给指定的请求头赋的值。

xhr.getResponseHeader()

获取相应响应头字段的信息。

参数:

  • header:要获取的响应头的值的名称

xhr.getAllResponseHeaders()

取得包含全部响应头部信息的长字符串。

new FormData()

XMLHttpRequest level2级接口。

FormData为序列化表单以及建立与表单格式相同的数据(用于XHR传输)提供了便利。

能够这样向FormData构造函数传入表单元素来填入键值对:

var data = new FormData(document.forms[0]);

也可使用append方法添加任意多个键值对:

var data = new FormData();
data.append('name', 'Bonnie');

FormData对应数据的"Content-Type"为"multipart/form-data",这也是该表头的默认值,故使用FormData能够没必要明确为Content-Type设置值,这是它的方便之处。

3. 使用范例:GET请求

写法步骤:

  1. 建立XMLHttpRequest对象:var xhr=new XMLHttpRequest()
  2. 指定xhr.onreadystatechange事件监听函数,在函数中先检测readyState属性(表示请求/响应的阶段)为4(表完成),再检测相应状态(xhr.status>=200&&xhr.status<300)||xhr.status==304) ,再在页面指定地方接受xhr.responseText(响应返回的文本)
  3. 执行xhr.open("GET",URL,是否异步)
  4. xhr.send(null)

实例:

<div>
    <button id="btn">Apples</button>
</div>
<div id="target">
</div>
<script>
  var button=document.getElementById("btn");
  button.onclick=handleButtonPress;
  
  function handleButtonPress(e) {
    var xhr=new XMLHttpRequest();//建立XMLHttpRequest对象

    xhr.onreadystatechange=function(){
      if (xhr.readyState==4) {//xhr.readyState:该属性表示请求/响应过程的当前活动阶段,4为完成,其值每变化一次都会触发一次readystatechange事件
        if ((xhr.status>=200&&xhr.status<300)||xhr.status==304) {//xhr.status:响应的状态
        //304状态码:客户端已经执行了GET,但文件未发生变化,即服务器若是发现资源没有改变过,那么就会返回304,告诉浏览器,我没变过,你去读缓存吧,因而浏览器也不用从服务器拉数据了
            document.getElementById("target").innerHTML=xhr.responseText;//xhr.responseText:做为响应主体被返回的文本
        }
        else{
            document.getElementById("target").innerHTML="Request was unsuccessful: "+xhr.status;
        }
      }
    }

    xhr.open("GET","example.html",true);//要发送的类型、请求的URL和是否异步发送
    xhr.send(null);//发送做为请求主体要发送的数据 
  }
</script>

Tips:GET请求常常会发生查询字符串格式有问题的错误。解决方法:查询字符串中每一个参数的名称和值都必须使用encodeURIComponent()进行编码。如下是一个向URL末尾添加查询字符串参数的方法:

function addUrlParam(url, name, value) {
    url += ( url.indexOf('?') === -1 ? '?' : '&');
    url += encodeURIComponent(name) + '=' + encodeURIComponent(value);
  }

3. 使用范例:POST请求(发送json数据)

写法步骤

  1. 处理提交按钮默认行为:若是提交按钮button没有设置type="button",那么其默认type为submit,要先调用e.preventDefault()取消按钮提交表单的默认行为。
  2. 准备好POST数据:经过DOM获取表单数据,并将其转换为Object类型,再用JSON.stringify转换为json字符串。
  3. 建立XMLHttpRequest实例:var xhr=new XMLHttpRequest()
  4. 指定xhr.onreadystatechange事件处理函数:在函数中先检测readyState属性为4,再检测相应状态(xhr.status>=200&&xhr.status<300)||xhr.status==304) ,再处理请求的响应文本xhr.responseText。若是获得的响应文本也是json字符串,那么也须要用JSON.parse方法将其从JSON字符串解析为Object。
  5. xhr.open("POST",URL,是否异步)。
  6. 设置请求头字段:xhr.setRequestHeader("Content-Type","application/json")设置请求头段Content-Type为application/json,告诉服务器在发送json数据。
  7. xhr.send(2.中准备好的json字符串)

实例:

<form id="fruitform" method="post" action="localhost:3000/form">
    <p>Bsnanas:</p>
    <p><input name="bananas" value="2"/></p>
    <p>Apples:</p>
    <p><input name="apples" value="5"/></p>
    <p>Cherries:</p>
    <p><input name="cherries" value="20"/></p>

    <p>Total:</p>
    <div id="results">0 items</div>
    <button id="submit" type="submit">Submit Form</button>
</form>

<script>
  document.getElementById("submit").onclick=handleButtonPress;
  function handleButtonPress(e) {
    e.preventDefault();//取消按钮提交表单的默认行为
    var form=document.getElementById("fruitform");

    var formData=new Object();
    var inputElements=document.getElementsByTagName("input");
    for (var i=0;i<inputElements.length;i++) {
        formData[inputElements[i].name]=inputElements[i].value;
    }//将表单提交的数据转换为object类型

    var xhr=new XMLHttpRequest();//建立XMLHttpRequest()对象
    xhr.onreadystatechange= function(){//为xhr.onreadystatechange设置事件监听函数,readystatechange改变的时候触发
      if (xhr.readyState==4) {
        if (xhr.status>=200&&xhr.status<300||xhr.status==304) {
          var data=JSON.parse(xhr.responseText);//把JSON数据解析为对象
          document.getElementById("results").innerHTML="You ordered "+data.total+" items";
        }
      }
    }
    xhr.open("post",form.action,true);//xhr.open()设置post方法,发送到的URL,是否异步
    xhr.setRequestHeader("Content-Type","application/json");//设置请求的首部字段Content-Type为application/json,告诉服务器在发送json数据
    xhr.send(JSON.stringify(formData));//浏览器向服务器发送数据前,要把数据从Object转换为JSON字符串
  }
</script>

4. 使用范例:POST请求(发送表单默认格式数据)

写法步骤:

  1. 处理提交按钮默认行为:若是提交按钮button没有设置type="button",那么其默认type为submit,要先调用e.preventDefault()取消按钮提交表单的默认行为。
  2. 准备好POST数据:经过DOM获取表单数据,并将其处理为字符串"name1=value1&name2=value2...namen=valuen&"。
  3. 建立XMLHttpRequest实例:var xhr=new XMLHttpRequest()
  4. 指定xhr.onreadystatechange事件处理函数:在函数中先检测readyState属性为4,再检测相应状态(xhr.status>=200&&xhr.status<300)||xhr.status==304) ,再处理请求的响应文本xhr.responseText。
  5. xhr.open("POST",URL,是否异步)。
  6. 设置请求头字段:xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),告诉服务器在发送x-www-form-urlencoded数据。
  7. xhr.send(2.中准备好的字符串)。

实例:

<script>
  document.getElementById("submit").onclick=handleButtonPress;
  
  function handleButtonPress(e) {
    e.preventDefault();//取消按钮提交表单的默认行为
    var form=document.getElementById("fruitform");

    var formData="";
    var inputElements=document.getElementsByTagName("input");
    for (var i=0;i<inputElements.length;i++) {
        formData+=inputElements[i].name+"="+inputElements[i].value+"&";
    }//将表单提交的数据转换为编码表单数据的默认方式(application/x-www-form-urlencoded编码)。

    var xhr=new XMLHttpRequest();//建立XMLHttpRequest()对象
    xhr.onreadystatechange=function() {//为xhr.onreadystatechange设置事件监听函数,readystatechange改变的时候触发
      if(xhr.readyState == 4) {
        if(xhr.status >= 200 && xhr.status < 300 || xhr.status==304) {
          document.getElementById("results").innerHTML = xhr.responseText;
        }
      }
    }
    xhr.open("post",form.action,true);//xhr.open()设置post方法,发送到的URL,是否异步
    xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//设置请求的首部字段Content-Type为application/json,告诉服务器在发送json数据
    xhr.send(formData);//浏览器向服务器发送数据前,要把数据从Object转换为JSON字符串
  }
</script>

5. 使用范例:POST请求(发送FormData数据)

var data = new FormData(document.forms[0]);//能够这样向FormData构造函数传入表单元素来填入键值对
/*也可使用append方法添加任意多个键值对。
var data = new FormData();
data.append('name', 'Bonnie');
*/
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
    if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
      console.log(xhr.responseText)
    }
  }
}
xhr.open('POST', 'post.php', true);
xhr.send(data);

2、jQuery的$.ajax()

http://api.jquery.com/jQuery.ajax/

1. 简介

执行Ajax请求。

2. 用例

(1)POST请求

$.ajax({
  method: 'POST',
  url:'example.php',
  data: {
    name: 'Bonnie',
    age: 26
  },
  dataType:'json'
}).done(function(msg){
  console.log(msg);
})

(2)请求的三种回调函数

$.ajax('example.php')
  .done(function(){
    alert('success');
  })
  .fail(function() {
    alert('error');
  })
  .always(function() {
    alert('complete')
  })

3.API

$.ajax(url[, settings])

url

请求的地址。

settings

这里列出一些重点配置属性:

contentType

default 'application/x-www-form-urlencoded; charset=UTF-8')

告诉服务器发送的数据类型。

crossDomain

default: false for same-domain requests, true for cross-domain requests)

是否跨域

data

Type: object or string or array)

要发送到服务器的数据。

dataType

default: Intelligent Guess (xml, json, script, or html)

Type: String

The type of data that you're expecting back from the server. If none is specified, jQuery will try to infer it based on the MIME type of the response (an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string)

dataTye字段指明你指望从服务器返回的数据类型,若是没有指定值,那么jQuery将尝试根据response的MIME类型来推断该数据类型(XML MIME类型将产生XML, 1.4版本的JSON将产生JavaScript对象,1.4版本的script将产生script,其余类型将返回字符串)

实践中遇到的问题:

  • 若是服务端php不指定header类型,那么response数据默认分配成text/html;此时,若客户端ajax不指定dataType,则在done里接收的data为string类型,这样还须要JSON.parse对其进行处理

  • 若是服务端php指定header类型为application/json,那么response的数据类型就为JSON字符串;此时,若客户端ajax不指定dataType,则在done里接收的data就为JavaScript object类型,这样就不须要经过JSON.parse对其进行处理。

jqXHR.done(function(data, textStatus, jqXHR){})

请求成功的回调函数

jqXHR.fail(function(jqXHR, textStatus, errorThrown){})

请求错误的回调函数

jqXHR.always(funciton(ata | jqXHR,textStatus,jqXHR | errorThrown){})

请求成功和失败都会执行的回调函数。

3、ES6的Fetch

1.简介

Fetch API提供了一个获取资源的借口(包括跨域)。它提供了许多与XMLHttpRequest相同的功能,但被设计成更具可扩展性和高效性。

Fetch 的核心在于对 HTTP 接口的抽象,包括 Request,Response,Headers,Body,以及用于初始化异步请求的 global fetch。

[Service Workers]s(https://developer.mozilla.org/zh-CN/docs/Web/API/Service_Worker_APIs) 是大量使用Fetch的API的一个示例。

fetch()方法

它返回一个 promise,这个promise会在请求响应后被resolve,并传回Response对象。

当遇到网络错误时,fetch()返回的promise会被reject,并传回TypeError。

成功的fetch()检查不只要包括promise被resolve,还要包括Response.ok属性为true.

fetch规范与jQuery.ajax()的不一样:

  • 当接收到一个表明错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即便该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (可是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。
  • 默认状况下,fetch 不会从服务端发送或接收任何 cookies, 若是站点依赖于用户 session,则会致使未经认证的请求。若是要发送 cookies,必须设置 credentials 选项

2.用例

(1)GET请求-获取json数据

fetch(urlStr)
  .then( res => res.json()) //res是一个response对象,并非咱们指望的json结果。为了获取JSON内容,咱们须要使用 json()方法。res.json()方法返回的也是一个promise对象,因此须要再一次地使用then()
  .then( myJson => {
    console.log(myJson)
  })

(2)用例:POST请求-发送json数据

fetch(urlStr, {
  method: 'POST', // *GET, POST, PUT, DELETE, etc.
  body: JSON.stringify(data),//须要和请求头字段Content-Type保持一致。这里是发送json字符串
  headers: {
    'content-type': 'application/json'
  },
  /* or:
  headers: new Headers({
    'Content-Type': 'application/json'
  })
  
  */
})
.then(res => res.json())
.catch(error => console.error('Error:', error))
.then(data => console.log(data))

加上对请求是否成功的验证:

fetch(urlStr, {
  method: 'POST', // *GET, POST, PUT, DELETE, etc.
  body: JSON.stringify(data),//须要和请求头字段Content-Type保持一致。这里是发送json字符串
  headers: {
    'content-type': 'application/json'
  },
})
.then(res => {
  if(res.ok) {
    return res.json();
  }
  throw new Error('Network response was not ok.');
 })
.catch(error => console.error('Error:', error.message))
.then(data => console.log(data))

3. API

(1) Body

Fetch API中的Body类表明Response/Request的body,容许你声明其内容类型是什么以及应该如何处理。

Body类由Response类和Request类实现,这为对象response和request提供了一个相关联的body(字节流)

属性
Body.bodyUsed

只读:包含一个指示body是否被读取过的 Boolean 值。

方法
Body.json()

使用一个 JSON 对象来读取 Response流中的数据,并将bodyUsed状态改成已使用。

返回:一个promise, resolve的结果是Json 对象 而非字符串(即通过JSON.parse()解析过的JSON字符串)

Body.formdata()

使用一个 FormData 对象来读取 Response流中的数据,并将bodyUsed状态改成已使用。

返回: 一个 Promise,resolve的结果是FormData 对象。

Body.text()

使用一个USVString (文本) 对象来读取 Response流中的数据,并将bodyUsed状态改成已使用。

返回:一个包含USVString对象 (text)的Promise,resolve的结果的编码为UTF-8。

注意: 其与Body.json()方法的区别:一样是请求json字符串文本:

  • 若是使用res.json(),那么resolve的结果直接是JavaScript对象(或数组)
  • 若是使用res.text(),那么resolve的结果是json字符串,须要使用JSON.parse()才能获得JavaScript对象(或数组)
Body.arrayBuffer()

使用一个buffer数组来读取 Response流中的数据,并将bodyUsed状态改成已使用。

返回:A promise that resolves with an ArrayBuffer.

Body.blob()

使用一个Blob对象来读取Response流中的数据,并将bodyUsed状态改成已使用。

返回:A promise that resolves with a Blob.

(2)Headers

Headers 接口容许您对HTTP请求和响应头执行各类操做。 这些操做包括检索,设置,添加和删除.

构造函数

let myHeader = new Headers()

append()

给现有的header添加一个值, 或者添加一个未存在的header并赋值.

delete()

从Headers对象中删除指定header

Headers.get()

从Headers对象中返回指定header的第一个值.

(3)fetch方法的请求参数

{
    body: JSON.stringify(data), // must match 'Content-Type' header
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, same-origin, *omit
    headers: {
      'user-agent': 'Mozilla/4.0 MDN Example',
      'content-type': 'application/json'
    },
    method: 'POST', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, cors, *same-origin
    redirect: 'follow', // manual, *follow, error
    referrer: 'no-referrer', // *client, no-referrer
  }
method

请求的方法

headers

请求头信息

mode

请求的模式:

  • no-cors(default):该模式容许来自 CDN 的脚本、其余域的图片和其余一些跨域资源,但请求的 method 只能是HEAD、GET 或 POST。
  • same-origin:禁止跨域。若是一个请求是跨域的,那么将返回一个 error,这样确保全部的请求遵照同源策略。
  • cors:跨域请求。用来从第三方提供的 API 获取数据。该模式遵照 CORS 协议,并只有有限的一些 Header 被暴露给 Response 对象,可是 body 是可读的。
credentials

请求的凭据,如 omit、same-origin 或者 include。为了在当前域名内自动发送 cookie , 必须提供这个选项。

redirect

可用的重定向模式: follow (自动重定向), error (若是产生重定向将自动终止而且抛出一个错误), 或者 manual (手动处理重定向).

referrer

能够是 no-referrer、client或一个 URL

参考文档与资料

《JavaScript高级程序设计》21.1,21.2

https://developer.mozilla.org/zh-CN/docs/Web/Guide/AJAX
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

http://api.jquery.com/jQuery.ajax/

https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API#
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
https://developer.mozilla.org/zh-CN/docs/Web/API/Body
https://developer.mozilla.org/zh-CN/docs/Web/API/Request
https://developer.mozilla.org/zh-CN/docs/Web/API/Response
https://developer.mozilla.org/zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch

相关文章
相关标签/搜索