你还不会AJAX?

320 阅读5分钟

什么是ajax

ajax是 async javascript and xml(异步的javascript和xml),ajax的出现解决了网页局部刷新的效果 在前后端没有分离的时候,前端想要重新渲染页面,需要在后端生成一个新的html,然后前端页面也需要重新渲染一遍,这样非常消耗性能,因此google团队研发出了ajax时间局部刷新的效果,最早用于邮件中,后来由于功能之强大,被常用于前后端的数据交互请求中,局部刷新的效果就是只刷新某一块区域,而不是整个视图都重新渲染一遍。

ajax使用手册

  1. 核心ajax经典四步骤;
    • 创建一个XMLHttpRequest实例
    • 调用实例的open方法设置请求方法,请求地址,是否异步请求(默认true,异步请求);参数:open(method,url,async)
    • 监听实例的readystate改变
    • 发送请求
let xhr = new XMLHttpRequest();
xhr.open("get","./1.json");
xhr.onreadystatechange = () => {}
xhr.send();
  1. xhr实例的属性详解
    • readyState: 属性的状态值(原型链上找到)
      • 0 UNSENT 请求已经创建但未初始化
      • 1 OPENED 调用完open方法
      • 2 HEADERS_RECEIVED 请求头返回(head请求就可以在这个时间返回)
      • 3 LOADING 响应主体信息正在返回
      • 4 DONE 响应主体信息返回了
    • resopnse,responseText(一般为JSON字符串,需要转义),responseXML,responseType(响应的格式:"arraybuffer" , "blob" , "document" , "json" , and "text" ),responseURl(最终访问的url,包括重定向后的)
    • status: 网络状态码
    • statusText: 响应完成返回的状态信息
    • timeout: 超时时间
    • withCredentials: 允许携带资源凭证
    • getResponseHeader(''): 获取对应的响应头信息
    • getAllResponseHeaders(): 获取所有的响应头信息
    • setRequestHeader('',''): 设置请求头信息
    • upload: 上传的状态(常用在文件上传),通常使用xhr.upload.onprogress来了解文件上传的进度(e.loaded/e.total)
    • onreadystatechange(): 监听状态值变化,做相应的处理
    • ontimeout(): 设置超时时做的处理
    • onabort(): 设置中断的时候做的处理(例如在断网时存储已经做完的事情,常用在文件上传中)
    • onloadstart(): 在请求发送前触发的函数在状态值1-2间
    • onload(): 在状态值变为4之后触发
    • onloaded(): 在状态值为2(未响应)或者4(响应了)触发
    • onprocgress(): 在上传的时候,状态值为3以后触发,传入ProgressEvent,可以通过e.loaded/e.total来知道进度
    • onerror(): 在请求出错后执行(通常在断网时触发)
  2. 请求方式
    • GET类: get,head,options,delete...

    • POST类: post,put,patch...

    • 两者的区别:

      • GETPOST在官方定义中是没有明确的区别的,但是浏览器或者开发的时候,都有一套约定俗成的规范:

      GET请求传递给服务器的信息,除了请求头传递以外,要求基于URL问号传参传递给服务器xhr.open('GET', './1.json?lx=1&name=xxx')

      POST请求要求传递给服务器的信息,是基于请求主体传递xhr.send('lx=1&name=xxx')

      • GET传递的信息不如POST多,因为URL有长度限制「IE->2KB」,超过这个长度的信息会被自动截掉,这样导致传递内容过多,最后服务器收到的信息是不完整的!!POST理论上是没有限制的,但是传递的东西越多,速度越慢,可能导致浏览器报传输超时的错误,所以实际上我们会自己手动做限制!!
      • GET会产生缓存「浏览器默认产生的,不可控的缓存」:两次及以上,请求相同的API接口,并且传递的参数也一样,浏览器可能会把第一次请求的信息直接返回,而不是从服务器获取最新的信息!!xhr.open('GET', './1.json?lx=1&name=xxx&_'+Math.random()),在请求URL的末尾设置随机数,以此来清除GET缓存的副作用或者在webpack打包的时候做hash处理
      • POST相对于GET来讲更安全一些:GET传递的信息是基于URL末尾拼接,这个随便做一些劫持或者修改,都可以直接改了,而POST请求主体信息的劫持,没那么好做!!但是“互联网面前,人人都在裸奔”!!所以不管什么方式,只要涉及安全的信息,都需要手动加密「因为默认所有的信息传输都是明文的」!!
  3. HTTP状态码:
    • 200 OK 请求成且响应完成
    • 202 Accepted :服务器已接受请求,但尚未处理(异步)
    • 204 No Content:服务器成功处理了请求,但不需要返回任何实体内容
    • 206 Partial Content:服务器已经成功处理了部分 GET 请求(断点续传 Range/If-Range/Content-Range/Content-Type:”multipart/byteranges”/Content-Length….)
    • 301 Moved Permanently 永久转移 「域名迁移」
    • 302 Move Temporarily 临时转移 「负载均衡」post请求方法可能会被转换为get,无法预测请求方法
    • 304 Not Modified 走协商缓存
    • 305 Use Proxy 走代理
    • 307 Temporary Redirect 临时 重定向 可以预测请求方法
    • 400 Bad Request : 请求参数有误
    • 401 Unauthorized:权限(Authorization
    • 403 Forbidden 服务器拒绝执行「为啥可能会已响应主体返回」
    • 404 Not Found 地址错误
    • 405 Method Not Allowed 请求方式不被允许
    • 408 Request Timeout 请求超时
    • 500 Internal Server Error 未知服务器错误
    • 503 Service Unavailable 超负荷
    • 505 HTTP Version Not Supported 不支持该http版本
    • ......
  4. 发送的主体信息
    • form-data: 主要用于文件的上传或者表单数据提交
      xhr.setRequestHeader('Content-Type', 'multipart/form-data');
      ------
      let fd = new FormData;
      fd.append('lx', 0);
      fd.append('name', 'xxx');
      xhr.send(fd);
      
    • application/x-www-form-urlencoded: "lx=1$name=xx"的格式
      // 可以使用第三方工具qs.js,支持qs.stringify和qs.parse进行对象和urlencoded字符串之间的转换
      let qs = require("qs");
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      ------
      xhr.send(qs.stringify({
          lx: 0,
          name: 'xxx'
      }));
      
    • raw: 字符串格式
      普通字符串  -> text/plain
      JSON字符串 -> application/json  => JSON.stringify/parse  「常用」
      XML格式字符串 -> application/xml
      ......
      
    • binary进制数据文件[buffer/二进制]: 一般用于大文件上传和断点续传