AJAX详述

目录

1、什么是AJAX?

2、如何使用?

2.1 XMLHttpRequest 实例 ---- 属性介绍

XMLHttpRequest.readyState 

XMLHttpRequest.onreadystatechange

XMLHttpRequest.response

XMLHttpRequest.responseType

XMLHttpRequest.responseText

XMLHttpRequest.responseXML

 XMLHttpRequest.responseURL

XMLHttpRequest.status

 XMLHttpRequest.statusText

XMLHttpRequest.timeout

 XMLHttpRequest.ontimeout

XMLHttpRequest.withCredentials

XMLHttpRequest.upload

 2.3 XMLHttpRequest  实例方法

XMLHttpRequest.open() 

XMLHttpRequest.send()

XMLHttpRequest.setRequestHeader()

XMLHttpRequest.overrideMimeType()

XMLHttpRequest.getResponseHeader()

XMLHttpRequest.getAllResponseHeaders()

XMLHttpRequest.abort()

2.4 XMLHttpRequest 实例的事件

progress 事件

load 事件、error 事件、abort 事件

 loadend 事件

 readyStateChange、timeout事件详见实例事件属性。


1、什么是AJAX?

AJAX(Asynchronous JavaScript and XML)是一种用于向服务器异步发送 HTTP 请求并接收响应的技术。基于 XMLHttpRequest 对象 (异步的与服务器交换数据)、XML (作为转换数据的格式)等。(就是基于已有技术实现客户端向服务端后台能够异步发送http/https请求并接收来自服务端的回应) 

XML是一种文本传输形式,现在基本都是用JSON

HTTP与HTTPS的区别,详细介绍

2、如何使用?

基本流程:

  1. 创建 XMLHttpRequest 实例
  2. 发出 HTTP 请求
  3. 接收服务器传回的数据
  4. 更新网页数据

AJAX 只能向同源网址(协议、域名、端口都相同)发出 HTTP 请求,受同源策略限制

完整示例:

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function(){
  // 通信成功时,状态值为4
  if (xhr.readyState === 4){
    if (xhr.status === 200){
      console.log(xhr.responseText);
    } else {
      console.error(xhr.statusText);
    }
  }
};

xhr.onerror = function (e) {
  console.error(xhr.statusText);
};

xhr.open('GET', '/url', true);
xhr.send(null);

2.1 XMLHttpRequest 实例 ---- 属性介绍

下面 用 xhr 来表示 XMLHttpRequest 实例

XMLHttpRequest.readyState 

返回一个整数,表示实例对象的当前状态。该属性只读。

0表示 XMLHttpRequest 实例已经生成,但是实例的open()方法还没有被调用。
1表示open()方法已经调用,但是实例的send()方法还没有调用,仍然可以使用实例的setRequestHeader()方法,设定 HTTP 请求的头信息。
2表示实例的send()方法已经调用,并且服务器返回的头信息和状态码已经收到。
3表示正在接收服务器传来的数据体(body 部分)。这时,如果实例的responseType属性等于text或者空字符串,responseText属性就会包含已经收到的部分信息。
4表示服务器返回的数据已经完全接收,或者本次接收已经失败。

xhr.readyState等于4时,表明HTTP 请求已经成功。其他情况,都表示 HTTP 请求还在进行中。 

XMLHttpRequest.onreadystatechange

XMLHttpRequest.onreadystatechange属性指向一个监听函数。readystatechange事件发生时(实例的readyState属性变化),就会执行这个属性。 此外,调用实例 xhr.abort()方法,终止 XMLHttpRequest 请求,也会造成readyState属性变化,触发函数。

XMLHttpRequest.response

服务器返回的数据体(即 HTTP 回应的 body 部分)。它可能是任何数据类型,比如字符串、对象、二进制对象等等,具体的类型由XMLHttpRequest.responseType属性决定。该属性只读。

如果本次请求没有成功或者数据不完整,该属性等于null。但是,如果responseType属性等于text或空字符串,在请求没有结束之前(readyState等于3的阶段),response属性包含服务器已经返回的部分数据

XMLHttpRequest.responseType

属性是一个字符串,表示服务器返回数据的类型。这个属性是可写的,可以在调用open()方法之后、调用send()方法之前,设置这个属性的值,告诉服务器返回指定类型的数据。如果responseType设为空字符串,就等同于默认值text。可以为以下值:

“”(空字符串)等同于text,表示服务器返回文本数据。
arraybufferArrayBuffer 对象,表示服务器返回二进制数组。
blobBlob 对象,表示服务器返回二进制对象。
documentDocument 对象,表示服务器返回一个文档对象。
jsonJSON 对象。
text字符串。

text类型适合大多数情况,而且直接处理文本也比较方便。document类型适合返回 HTML / XML 文档的情况。blob类型适合读取二进制数据,比如图片文件 

 blob

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'blob';

xhr.onload = function(e) {
  if (this.status === 200) {
    var blob = new Blob([xhr.response], {type: 'image/png'});
    // 或者
    var blob = xhr.response;
  }
};

xhr.send();

ArrayBuffer

var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';

xhr.onload = function(e) {
  var uInt8Array = new Uint8Array(this.response);
  for (var i = 0, len = binStr.length; i < len; ++i) {
    // var byte = uInt8Array[i];
  }
};

xhr.send();
XMLHttpRequest.responseText

返回从服务器接收到的字符串,该属性为只读。只有 HTTP 请求完成接收以后,该属性才会包含完整的数据。

var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);

xhr.responseType = 'text';
xhr.onload = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText);
  }
};

xhr.send(null);
XMLHttpRequest.responseXML

返回从服务器接收到的 HTML 或 XML 文档对象,该属性为只读。如果本次请求没有成功,或者收到的数据不能被解析为 XML 或 HTML,该属性等于null。 回应的Content-Type头信息等于text/xmlapplication/xml。这要求在发送请求前,XMLHttpRequest.responseType属性要设为document。如果 HTTP 回应的Content-Type头信息不等于text/xmlapplication/xml,但是想从responseXML拿到数据(即把数据按照 DOM 格式解析),那么需要手动调用XMLHttpRequest.overrideMimeType()方法,强制进行 XML 解析。

该属性得到的数据,是直接解析后的文档 DOM 树。

var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);

xhr.responseType = 'document';
xhr.overrideMimeType('text/xml');

xhr.onload = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseXML);
  }
};

xhr.send(null);
 XMLHttpRequest.responseURL

该属性是字符串,表示发送数据的服务器的网址。

XMLHttpRequest.status

返回一个整数,表示服务器回应的 HTTP 状态码。一般来说,如果通信成功的话,这个状态码是200;如果服务器没有返回状态码,那么这个属性默认是200。请求发出之前,该属性为0。该属性只读。

  • 200, OK,访问正常
  • 301, Moved Permanently,永久移动
  • 302, Move temporarily,暂时移动
  • 304, Not Modified,未修改
  • 307, Temporary Redirect,暂时重定向
  • 401, Unauthorized,未授权
  • 403, Forbidden,禁止访问
  • 404, Not Found,未发现指定网址
  • 500, Internal Server Error,服务器发生错误
if (xhr.readyState === 4) {
  if ( (xhr.status >= 200 && xhr.status < 300)
    || (xhr.status === 304) ) {
    // 处理服务器的返回数据
  } else {
    // 出错
  }
}
 XMLHttpRequest.statusText

属性返回一个字符串,表示服务器发送的状态提示。不同于status属性,该属性包含整个状态信息,比如“OK”和“Not Found”。在请求发送之前(即调用open()方法之前),该属性的值是空字符串;如果服务器没有返回状态提示,该属性的值默认为”“OK”。该属性为只读属性

XMLHttpRequest.timeout

设置超时时间(毫秒),为 0 则表示没有限制

 XMLHttpRequest.ontimeout

请求超时的监听

var xhr = new XMLHttpRequest();
var url = '/server';

xhr.ontimeout = function () {
  console.error('The request for ' + url + ' timed out.');
};

xhr.onload = function() {
  if (xhr.readyState === 4) {
    if (xhr.status === 200) {
      // 处理服务器返回的数据
    } else {
      console.error(xhr.statusText);
    }
  }
};

xhr.open('GET', url, true);
// 指定 10 秒钟超时
xhr.timeout = 10 * 1000;
xhr.send(null);
XMLHttpRequest.withCredentials

属性是一个布尔值,表示跨域请求时,用户信息(比如 Cookie 和认证的 HTTP 头信息)是否会包含在请求之中,默认为false,即向example.com发出跨域请求时,不会发送example.com设置在本机上的 Cookie(如果有的话)。

如果需要跨域 AJAX 请求发送Cookie,需要withCredentials属性设为true。注意,同源的请求不需要设置这个属性。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null);

为了让这个属性生效,服务器必须显式返回Access-Control-Allow-Credentials这个头信息。

XMLHttpRequest.upload

XMLHttpRequest 不仅可以发送请求,还可以发送文件,这就是 AJAX 文件上传。发送文件以后,通过XMLHttpRequest.upload属性可以得到一个对象,通过观察这个对象,可以得知上传的进展。主要方法就是监听这个对象的各种事件:loadstart、loadend、load、abort、error、progress、timeout。

假定网页上有一个<progress>元素。获取上传进度:

function upload(blobOrFile) {
  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/server', true);
  xhr.onload = function (e) {};

  var progressBar = document.querySelector('progress');
  xhr.upload.onprogress = function (e) {
    if (e.lengthComputable) {
      progressBar.value = (e.loaded / e.total) * 100;
      // 兼容不支持 <progress> 元素的老式浏览器
      progressBar.textContent = progressBar.value;
    }
  };

  xhr.send(blobOrFile);
}

upload(new Blob(['hello world'], {type: 'text/plain'}));

 2.2 XMLHttpRequest  事件监听属性介绍

onloadstartloadstart 事件(HTTP 请求发出)的监听函数
onprogressprogress事件(正在发送和加载数据)的监听函数
onabortabort 事件(请求中止,比如用户调用了abort()方法)的监听函数
onerrorerror 事件(请求失败)的监听函数
onloadload 事件(请求成功完成)的监听函数
ontimeouttimeout 事件(用户指定的时限超过了,请求还未完成)的监听函数
onloadendloadend 事件(请求完成,不管成功或失败)的监听函数
xhr.onload = function() {
 var responseText = xhr.responseText;
 console.log(responseText);
 // process the response.
};

xhr.onabort = function () {
  console.log('The request was aborted');
};

xhr.onprogress = function (event) {
  console.log(event.loaded);
  console.log(event.total);
};

xhr.onerror = function() {
  console.log('There was an error!');
};

progress事件的监听函数有一个事件对象参数,该对象有三个属性:loaded属性返回已经传输的数据量,total属性返回总的数据量,lengthComputable属性返回一个布尔值,表示加载的进度是否可以计算。所有这些监听函数里面,只有progress事件的监听函数有参数,其他函数都没有参数。

注意,如果发生网络错误(比如服务器无法连通),onerror事件无法获取报错信息。也就是说,可能没有错误对象,所以这样只能显示报错的提示。

 2.3 XMLHttpRequest  实例方法

XMLHttpRequest.open() 

open()方法用于指定 HTTP 请求的参数,或者说初始化 XMLHttpRequest 实例对象。它一共可以接受五个参数。

void open(
   string method,
   string url,
   optional boolean async,
   optional string user,
   optional string password
);
method表示 HTTP 动词方法,比如GETPOSTPUTDELETEHEAD等。
url表示请求发送目标 URL
async布尔值,表示请求是否为异步,默认为true。如果设为false,则send()方法只有等到收到服务器返回了结果,才会进行下一步操作。该参数可选。由于同步 AJAX 请求会造成浏览器失去响应(浏览器会停止,及DOM不再更新),许多浏览器已经禁止在主线程使用,只允许 Worker 里面使用。所以,这个参数轻易不应该设为false
user表示用于认证的用户名,默认为空字符串。该参数可选。
password表示用于认证的密码,默认为空字符串。该参数可选。

 注意,如果对使用过open()方法的 AJAX 请求,再次使用这个方法,等同于调用abort(),即终止请求。

XMLHttpRequest.send()

方法用于实际发出 HTTP 请求。它的参数是可选的,如果不带参数,就表示 HTTP 请求只包含头信息,也就是只有一个 URL,典型例子就是 GET 请求;如果带有参数,就表示除了头信息,还带有包含具体数据的信息体,典型例子就是 POST 请求。

发送GET

var xhr = new XMLHttpRequest();
xhr.open('GET',
  'http://www.example.com/?id=' + encodeURIComponent(id),
  true
);
xhr.send(null);

// 等同于
var data = 'id=' + encodeURIComponent(id);
xhr.open('GET', 'http://www.example.com', true);
xhr.send(data);

上面代码中,GET请求的参数,可以作为查询字符串附加在 URL 后面,也可以作为send方法的参数。

发送POST

var xhr = new XMLHttpRequest();
var data = 'email='
  + encodeURIComponent(email)
  + '&password='
  + encodeURIComponent(password);

xhr.open('POST', 'http://www.example.com', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(data);

注意,所有 XMLHttpRequest 的监听事件,都必须在send()方法调用之前设定。

发送数据格式

void send();
void send(ArrayBufferView data);
void send(Blob data);
void send(Document data);
void send(String data);
void send(FormData data);

发送二进制数据,最好使用ArrayBufferViewBlob对象,可以通过 Ajax 上传文件。 

var formData = new FormData();

formData.append('username', '张三');
formData.append('email', 'zhangsan@example.com');
formData.append('birthDate', 1940);

var xhr = new XMLHttpRequest();
xhr.open("POST", "/register");
xhr.send(formData);
function sendForm(form) {
  var formData = new FormData(form);
  formData.append('csrf', 'e69a18d7db1286040586e6da1950128c');

  var xhr = new XMLHttpRequest();
  xhr.open('POST', form.action, true);
  xhr.onload = function() {
    // ...
  };
  xhr.send(formData);

  return false;
}
//获取 form dom
var form = document.querySelector('#registration');
sendForm(form);

XMLHttpRequest.setRequestHeader()

方法用于设置浏览器发送的 HTTP 请求的头信息。该方法必须在open()之后、send()之前调用。如果该方法多次调用,设定同一个字段,则每一次调用的值会被合并成一个单一的值发送。

该方法接受两个参数。第一个参数是字符串,表示头信息的字段名,第二个参数是字段值。

 例:

xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Content-Length', JSON.stringify(data).length);  
//自定义请求头
xhr.setRequestHeader('token','')
xhr.send(JSON.stringify(data));
XMLHttpRequest.overrideMimeType()

方法用来指定 MIME 类型

XMLHttpRequest.getResponseHeader()

方法返回 HTTP 头信息指定字段的值,如果还没有收到服务器回应或者指定字段不存在,返回null。该方法的参数不区分大小写。

function getHeaderTime() {
  console.log(this.getResponseHeader("Last-Modified"));
}

var xhr = new XMLHttpRequest();
xhr.open('HEAD', 'yourpage.html');
xhr.onload = getHeaderTime;
xhr.send();
XMLHttpRequest.getAllResponseHeaders()

XMLHttpRequest.getAllResponseHeaders()方法返回一个字符串,表示服务器发来的所有 HTTP 头信息。格式为字符串。若无回应,则为null

XMLHttpRequest.abort()

方法用来终止已经发出的 HTTP 请求。调用这个方法以后,readyState属性变为4status属性变为0


2.4 XMLHttpRequest 实例的事件

progress 事件
var xhr = new XMLHttpRequest();

function updateProgress (oEvent) {
  if (oEvent.lengthComputable) {
    var percentComplete = oEvent.loaded / oEvent.total;
  } else {
    console.log('无法计算进展');
  }
}

xhr.addEventListener('progress', updateProgress);

xhr.open();
load 事件、error 事件、abort 事件
var xhr = new XMLHttpRequest();

xhr.addEventListener('load', transferComplete);
xhr.addEventListener('error', transferFailed);
xhr.addEventListener('abort', transferCanceled);

xhr.open();

function transferComplete() {
  console.log('数据接收完毕');
}

function transferFailed() {
  console.log('数据接收出错');
}

function transferCanceled() {
  console.log('用户取消接收');
}
 loadend 事件

abortloaderror这三个事件,会伴随一个loadend事件,表示请求结束,但不知道其是否成功。

xhr.addEventListener('loadend', loadEnd);

function loadEnd(e) {
  console.log('请求结束,状态未知');
}
 readyStateChange、timeout事件详见实例事件属性。

内容总结来自于:https://javascript.ruanyifeng.com/bom/ajax.html#toc28

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值