首页 > 其他分享 >彻底搞懂Ajax,Promise,Axios

彻底搞懂Ajax,Promise,Axios

时间:2022-10-19 19:44:56浏览次数:48  
标签:Axios XMLHttpRequest 请求 url send xhr Promise 搞懂

一、ajax

  • AJAX:异步 JavaScript 和 XML,用来发送异步请求。有了Ajax之后,在无需重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
      Ajax是基于现有的Internet标准,联合使用了XMLHttpRequest,JS/DOM,CSS,XML等技术。
      它有个较大的缺陷就是业务逻辑需要在回调函数中执行,如果多个请求存在依赖关系,就会产生回调地狱问题,对读写理解困难。

XHR对象常用方法

(1)XMLHttpRequest.open()
初始化一个请求。已激活的请求再次调用此方法时,相当于调用了abort(),会中断上一个请求。
  当设置了async(第三个参数)true之后,请规定onreadystatechange事件中的就绪状态执行响应函数。

(2)XMLHttpRequest.send()
向服务器发送http请求。如果open()中定义的是异步请求,则此方法会在请求发起后立刻返回;如果是同步,则在请求返回后才执行。

(3)XMLHttpReqeust.abort()
当请求已经发出,则立刻中断请求。将readystate设置为0,立刻调用onreadystatechange方法执行回调函数。

(4)XMLHttpRequest.setReqeustHeader()
用于给HTTP请求增加自定义请求头,在open()之后,send()之前定义。设置多个相同的请求头,在发起时会进行合并。

(5)XMLHttpRequest.getResponseHeader()
根据名称获取HTTP请求头,如果需要一次请获取全部,请使用getAllHeetResponseHeader()方法。

XMLHTTP.readyState的五种状态

0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了

  • (0)未初始化

此阶段确认XMLHttpRequest对象是否创建,并为调用open()方法进行未初始化作好准备。值为0表示对象已经存在,否则浏览器会报错--对象不存在。

  • (1)载入

此阶段对XMLHttpRequest对象进行初始化,即调用open()方法,根据参数(method,url,true)完成对象状态的设置。并调用send()方法开始向服务端发送请求。值为1表示正在向服务端发送请求。

  • (2)载入完成

此阶段接收服务器端的响应数据。但获得的还只是服务端响应的原始数据,并不能直接在客户端使用。值为2表示已经接收完全部响应数据。并为下一阶段对数据解析作好准备。

  • (3)交互

此阶段解析接收到的服务器端响应数据。即根据服务器端响应头部返回的MIME类型把数据转换成能通过responseBody、responseText或responseXML属性存取的格式,为在客户端调用作好准备。状态3表示正在解析数据。

  • (4)完成

此阶段确认全部数据都已经解析为客户端可用的格式,解析已经完成。值为4表示数据解析完毕,可以通过XMLHttpRequest对象的相应属性取得数据。

    • 概而括之,整个XMLHttpRequest对象的生命周期应该包含如下阶段:
      创建-初始化请求-发送请求-接收数据-解析数据-完成

封装一个原生的Ajax请求

ajaxRequest(method, url, data, callback) {
  let xhr;
  if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
  } else {
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
  }
  
  if (method.toLocalCase() === "get") {
    url = url + this.getParams(data);
    xhr.open(method, url, true);
    xhr.send();
  } else { // post
    xhr.open(method, url, true);
    xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
    data ? xhr.send(data) : xhr.send()
  }

  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4) {
      if (xhr.state === 200) {
        // 约定返回字符串格式,如是xml格式使用responseXML
        callback(xhr.responseText);
      } else {
        reject(new Error(xhr.statusText))
    } else {
      if (xhr.readyStatue === 0) {
        alert("请求已取消");
      }
    }
  }
}

buildGetParams(obj) {
  if (!obj || obj.keys.length === 0) return '';
  let str = Object.keys(obj).reduce(function(prev, cur, index) {
    if (index === 1) {
      prev = prev + '=' + obj[prev]
    }
    return prev + (prev ? '&' : '') + cur.toString() + '=' + obj[cur]
  })
}

二、Promise

Promise对象由ES6提供,它表示一个尚未完成且预计在未来完成的异步操作。Promise 仅仅是一种决定异步任务状态确定时会出现什么结果的技术。它本身并不提供异步请求功能,更不能替代Ajax。

Promise将异步请求的回调操作,改成了同步的链式写法,最直观的就是使用Promise处理ajax请求时,可以解决回调地狱问题;另外,Promise封装了统一的接口,使得控制异步操作变得更加简单。

  但它的缺点也比较明显,发起的Promise无法取消中断,其次,如果不设捕获异常的回调函数,Promise内部抛出的错误无法反应到外部出来。另外,未执行完成的Promise也无法确定是刚开始还是即将结束(即ajax的readyState在哪个过程)。

创建Promise

let promise = new Promise((resolve, reject) => {
  // 执行结束需要使用resolve或reject将结果返回
})

Promise的基本API

Promise有三种状态,分别是 pending:执行状态、fulfilled:已成功、rejected:已失败。
pending只能改变为fulfilled或rejected其中一种,且状态一旦改变,将凝固不再改变。即使再次修改,该操作也会被忽略。

使用Promise写法实现Ajax请求

getRequest(url) {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.open('get', url, true);
    xhr.send();
  
    xhr.onreadystatechange() {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          resolve(JSON.parse(xhr.responseText));
        } else {
          reject(new Error(xhr.statusText))
        }
      }
    }
  })
}

// 调用
this.getRequest("http://demo-domain:8080?name=test").then(resp => {
  console.log(resp)
})

Axios

Axios是一个基于Promise的http库,支持node端和浏览器端,支持拦截器、自定义请求头、取消请求等高级配置,支持自动转换JSON,也支持npm包的使用。总之,优点多多,用就对了…

自定义axios实例

let request = axios.create({
  baseURL: 'http://some-domain.com/api/',
  timeout: 1000,
  headers: { 'X-Custom-Header': 'footbar' }
})

常用axios的请求配置

  • 以下配置中,只有 url 是必须的,如果没有配置method,将默认使用get方法。
  • url: ‘/user’ 用户请求服务器资源的 URL
  • method: ‘post’ 创建请求时使用的方法
  • baseURL: ‘http://demo-domain:8080/api/’ 自动加在URL(非绝对路径时)前的路径
  • headers: { ‘x-Requested-With’: ‘XMLHttpRequest’ } 自定义请求头
  • params: { ‘ID’: ‘12345’ } 与请求一起发送的URL参数,当method指定为GET时使用
  • data: { ‘name’: ‘zhangfs’ } 请求主体参数,用于PUT,POST,PATCH方法
  • timeout: 8000 请求超时时间,0表示无超时;超过时间请求被中断
  • withCredentials: false 请求跨域时是否需要使用凭证
  • auth: { username: ‘zhangfs’ } 用于HTTP基础验证,将复写Authorization头
  • proxy: {
    host: ‘127.0.0.1’,
    port: 9000,
    } 代理服务器的主机名与端口,将设置Proxy-Authoriation
  • cancelToken: new CancelToken(function(cancel) { … }) 指定取消请求的cancel token

请求拦截器

  • 在请求或响应被 then 或 catch 处理前拦截它们。如果自定义了axios实例如request,则使用 request.interceptors.xxx
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

标签:Axios,XMLHttpRequest,请求,url,send,xhr,Promise,搞懂
From: https://www.cnblogs.com/maxiaohu/p/16807495.html

相关文章

  • Promise.race
    1.Promise.race的使用:1constpromise1=newPromise((resolve,reject)=>{2setTimeout(resolve,500,'one');3});4constpromise2=newPromise((r......
  • 一文搞懂Undo Log版本链与ReadView机制如何让事务读取到该读的数据
     在MySQL的数据表中,存储着一行行的数据记录,对每行数据而言,不仅仅记录着我们定义的字段值,还会隐藏两个字段:row_trx_id和roll_pointer,前者表示更新本行数据的事务id......
  • 我的Vue之旅 07 Axios + Golang + Sqlite3 实现简单评论机制
    第三期·使用Vue3.1+TailWind.CSS+Axios+Golang+Sqlite3实现简单评论机制效果图CommentArea.vue我们需要借助js的Data对象把毫秒时间戳转化成UTCStrin......
  • vue之axios
    什么是axios?Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中。特性1从浏览器中创建XMLHttpRequests2从node.js创建http请求3支持PromiseAPI4......
  • 一文全搞懂postgresql的权限
    权限结构图pg中权限至上而下层次分明,首先要了解pg的逻辑架构,如下图需要注意的是在如上架构中数据库是严格分开的,这意味着不能同时使用两个不同的数据库,而模式不是严格分开的......
  • 我的Vue之旅 07 Axios + Golang + Sqlite3 实现简单评论机制
    第三期·使用Vue3.1+Axios+Golang+Sqlite3实现简单评论机制效果图CommentArea.vue我们需要借助js的Data对象把毫秒时间戳转化成UTCString()。并在模板......
  • 多层嵌套 promise then 执行顺序
    在看js事件循环的时候,看到一个有趣的promisethen执行顺序的题,想了好久,终于想明白了,这里记录一下。 大家先想下这里的执行顺序是什么。newPromise(resolve=>{......
  • 手写promise
    分析对于promise的复现,我们得先考虑promise的使用。使用时可以进行new操作,那么可以用构造函数获取class来构建存在then方法可以调用resolve和reject方法有三种状态p......
  • axios : Promise based HTTP client for the browser and node.js
    axiosPromisebasedHTTPclientforthebrowserandnode.jsFeaturesMake​​XMLHttpRequests​​fromthebrowserMake​​http​​requestsfromnode.jsSupportsthe......
  • Promise 捕获程序中的失败
    代码varA=newPromise(function(resolve,reject){console.log('dosth.');setTimeout(()=>{console.log('~~~~~');resolve('ok');//reject......