JS —— ajax

浏览器在XMLHttpRequest类上定义了他们的HTTP API。 这个类的每一个实例都是一个独立的请求/响应对,这个对象的属性和方法允许指定请求细节和提取响应数据。

一、实例化XMLHttpResquest()

使用这个HTTP API的第一步就是实例化一个XMLHttpRequest对象:

var requestObj new XMLHttpRequest();

当然,实际开发中,不会这么简单,我们还要考虑兼容早版本的IE的问题,在IE5和IE6中它只是一个ActiveX对象。IE7之前的版本不支持非标准化的XMLHttpRequest()构造函数。我们需要这样写:

if (window.XMLHttpRequest) {
    requestObj = new XMLHttpRequest();
} else {
    requestObj = new ActiveXObject("Microsoft.XMLHTTP")//兼容早版本的ie, 如IE5 IE6
}

除了实例化一个XMLHttpRequest对象,我们也可以重用已有的对象,但要注意,这样会终止之前通过该对象挂起的任何请求。

请求和响应的组成

一个http请求由4部分组成:

  • 方法或“动作”
  • 请求的 url
  • 可选的请求头集合,可能包含身份验证信息
  • 可选的请求主体

HTTP响应包含3部分:

  • 状态码,显示请求的状态,如是否成功
  • 响应头集合
  • 响应主体

二、指定请求

发起HTTP请求的下一步是调用XMLHttpRequest对象的open()方法:

request.open("方法", "URL")

open()方法需要指定两个必要部分:方法 和 url。第一个参数为“方法”,不区分大小写,但通常使用大写,常用的方法有 “GET” “POST”。GET 方法用于常规请求,它适用于当URL完全指定请求资源,请求对服务器没有任何副作用以及服务器响应是可缓存的。POST方法常用于HTML表单,它在请求主体中包含额外数据,且这些数据常需要存储到服务器的数据库上(副作用)。不同的额外数据服务器可能返回不同的数据。

除了POST和GET方法,还有“DELETE” “HEAD” “OPTION” “PUT”等方法。他们都可以作为open()方法的第一个参数。

open()方法还有第三个参数,用来指定方法是同步还是异步的。而默认是异步的,这个在文章后面会细讲。

三、设置请求头

如果有请求头的话,我们可以通过

requestObj.setRequestHeader("Content-Type",  "  ")

来设置请求头。
要注意的是:对相同的头调用setRequestHeader()多次,新值不会取代旧值,相反,HTTP请求将包含这个头的多个副本或这个头将指定多个值。并不是所有的头都可以设置,如“Content-length””Date” “Referer” 和 “User-Agent”等,XMLHttpRequest将自动添加这些头而防止伪造它们。

四、发送请求

使用XMLHttpRequest的最后一步是指定可选的请求主体并向服务器发送它。使用send()方法:

requestObj.send(null)

GET方法没有主体,我们在send()方法中传入null或省略这个参数。POST请求通常拥有主体,同时应该配合setRequestHeader()指定的“Content-Type”头。

到现在,我们可以看到一个完整的发送请求的过程:

var requestObj;

if (window.XMLHttpRequest) {
    requestObj = new XMLHttpRequest();
} else {
    requestObj = new ActiveXObject("Microsoft.XMLHTTP")
}

requestObj.open("方法", url, async);
requestObj.setRequestHeader("Content-Type", "xxxxxxxx") //根据方法设置相应的头
requestObj.send();

前面部分讲了如何 发送ajax请求_,下面部分是如何 _取得响应

五、取得响应

一个完整的HTTP响应由状态码、响应头集合和响应主体组成。这些都可以通过XMLHttpRequest对象的属性和方法使用。

  • status和statusText属性以数字和文本的形式返回HTTP状态码。
  • getResponseHeader()和getAllResponseHeaders()能查询响应头。
  • 响应主体可以从 reponseText 属性中得到文本形式,从responseXML中得到Document形式。

在send()方法发送后,我们需要知道我们的请求什么时候得到了响应,请求是否成功等,这时候我们就要用到XMLHttpResquest对象上的 readyState 属性,readyState属性是一个整数,它指定了请求的状态:

常量含义
UNSENT0open()尚未使用
OPENED1open()已调用
HEADERS_RECEIVED2接收到头部信息
LOADING3接收到响应主体
DONE4响应完成

通过readyState我们就可以知道当前的请求出于什么状态了,那我们怎么去监听readyState呢?其实在每次readyState改变的时候,都会触发readystatechange事件,而我们可以通过onreadystatechange属性去监听readystatechange事件。所以通过onreadystatechange属性就可以间接的监听到readyState的改变了。当然我们也可以使用addEventListener()方法来监听,但我们通常不这么做。

所以我们可以通过下面代码来获取响应信息:

requestObj.onreadystatechange = function() {  // 监听readyState的变化

  if (requestObj.readyState == 4) { // 判断响应是否完成
  
     if (requestObj.status == 200) {  // 判断请求是否成功
     
        console.log(resquestObj.responseText);
     }
     
  }
  
}

所以到这里,我们应该知道了一个完整的原生ajax请求是怎么样的了。

// 实例化XMLHttpRequest
var requestObj;
if (window.XMLHttpResquest) {
   requestObj = new XMLHttpRequest();
} else {
  requestObj = new ActiveXObject("Microsoft.XMLHTTP")
}

// 发送请求
requestObj.open("TYPE", "URL");
requestObj.setRequestHeader("Content-Type", .....);
requestObj.send();

// 获取响应
requestObj.onreadystatechange = function() {
  if (requestObj.readyState == 4) {
      if (requestObj.status == 200) {
         console.log(requestObj.reponseText);
      }
  }
}

六、同步请求

是否还记得前面说到,open()方法还有第三个参数,它指定请求是同步的还是异步的,而默认值为true, 使得请求为异步请求。我们可以给它传入false来实现同步请求。

requestObj.open(type, url, false);

这样我们就不需要去监听readyState的值来获知请求何时得到了响应了。

requestObj.open("TYPE", "URL", false);
requestObj.setRequestHeader("Content-Type", .....);
requestObj.send();

// 当请求得到响应才执行
if (requestObj.status != 200) throw new Error(request.statusText);

console.log(requestObj.reponseText);

同步请求是吸引人的,但是同步请求意味着什么呢?意味着由于JavaScript是单线程的,当send()方法调用后,请求发出,send()方法将阻塞这份代码,send()方法后面的代码都不会被执行,直到请求得到响应,如果连接的服务器响应慢,用户的浏览器UI就会被冻结。所以不是特殊情况,最好不用同步请求。

    原文作者:holyZhengs
    原文地址: https://segmentfault.com/a/1190000012837258
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞