学习记录--01Ajax---运行原理-原生Ajax封装

传统网站存在的问题

  1. 页面加载慢
  2. 表单提交就 如果一项内容不合格 需要重新填写所有表单的内容
  3. 页面跳转 重新加载页面 造成资源浪费 增加用户等待时间

Ajax

浏览器提供的方法,可以实现页面无刷新更新数据
定义
在不刷新页面的情况下,使用异步对象ajax(XMLHttpRequest)向服务器后台发送请求报文,拿到响应的数据之后,通过DOM操作方式局部更新当前页面


Ajax的应用场景

  1. 页面上拉加载更多数据
  2. 列表数据无刷新分页
  3. 表单项离开焦点数据验证
  4. 搜索框提示文字下拉列表

Ajax 运行环境

需要在网站环境中才能生效 可以使用Node创建的服务器


Ajax使用步骤

  1. 创建ajax对象
    var xhr = new XMLHttoRequest()
    IE5 和 IE6 不支持 new XMLHttoRequest() 要使用new ActiveXObject(“Microsoft.XMLHTTP”);
  2. 告诉ajax对象要向什么地方 以什么方式发生请求
    xhr.open('get','请求地址')
  3. 发送请求 请求体
    xhr.send()
  4. 获取服务器端响应到客户端的数据 ajax 发送需要时间 通过ajax底下的onload方法
    xhr.onload  = function(){
      //xhr.responseText  存储的地址
    }
    
    xhr.status 可以获取 http状态码
    可以通过xhr.getRequestHeader('Content-Type') 获取响应头文件的类型

Ajax运行原理及实现

  • 服务器大多数情况下会以JSON对象作为响应数据的格式,客户端拿到数据时会将JSON数据和HTML字符串进行品阶 并以DOM的形式响应到页面中

  • 在http请求与响应的过程汇总,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输---->{‘name’,‘ll’}

  • 将json字符串转换为json对象
    JSON.parse()


请求参数传递


get请求参数

xhr.open('get','https://gitbook.cn/?ref=csdn')

代码示例

<body>
  <input type="text" name="uname">
  <input type="text" name='upwd'>
  <input type="submit" id='btn'>

  <script>
    //创建ajax对象
    var xhr = new XMLHttpRequest();
    var btn = document.querySelector('#btn');
    var uname = document.querySelector('input[name=uname]');
    var upwd = document.querySelector('input[name=upwd]');
    btn.onclick = function(){
      var unameV = uname.value;
      var upwdV = upwd.value;
      console.log(unameV);
      xhr.open('get','http://localhost:3000/second?uname='+unameV+'&upwd='+upwdV);
      xhr.send();
      xhr.onload = function() {

      };
    }
  </script>
</body>

post请求方式

必须在请求报文中明确的声明请求参数的类型
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
请求数据写在send中
xhr.send('name=zhangsan&age=20');

代码示例

<body>
  <input type="text" name="uname">
  <input type="text" name='upwd'>
  <input type="submit" id='btn'>

  <script>
    //创建ajax对象
    var xhr = new XMLHttpRequest();
    var btn = document.querySelector('#btn');
    var uname = document.querySelector('input[name=uname]');
    var upwd = document.querySelector('input[name=upwd]');
    btn.onclick = function(){
      var unameV = uname.value;
      var upwdV = upwd.value;
      var paramts = 'uname='+unameV+'&upwd='+upwdV;
      xhr.open('post','http://localhost:3000/post');
      //设置参数格式
      xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
      xhr.send(paramts);
      xhr.onload = function() {
        console.log(xhr.responseText)
      };
    }
  </script>
</body>

请求参数格式

  1. application/x-www-form-urlencoded
    name=zhangsan&age=20&sex=男
  2. application/json
    {name: ‘zhangsan’,age: 20,sex: ‘男’}
    在请求头忠厚指定Content-Type属性的值是application/json,就是在告诉服务器端当前请求的参数的格式是json
    JSON.stringify 将json对象转换为json字符串 send中只能传入字符串

注意:

  • get请求是不能提交json对象数据格式的,传统网站的表单提交也是不支持json对象数据格式的
  • json对象就是没有方法的对象—字面量对象,构造函数就是Object

在服务器端获取传入数据 使用bodyParser时要使用app.use(bodyParser.json());


Ajax 异步编程

事件处理函数也是回调函数的一种
Ajax异步请求

Object.assign(被覆盖对象,覆盖对象) 对象覆盖


获取服务器端的响应


Ajax状态码

xhr.readystate //获取Ajax状态码
在创建ajax对象,配置ajax对象,发送请求,以及接受完服务器端响应数据,在这个过程中每一步都对应一个数值,这个数值就是ajax状态码

  • 0:请求未初始化 还没有调用open()
  • 1 请求已经建立,但是还没有发送 —没有调用send()
  • 2 请求已经发送
  • 3 请求正在处理中,通常响应中已经有部分数据可以使用了
  • 4 响应已经完成,响应数据已经接收完了,可以获取并使用服务器的响应了

onreadystatechange 事件

当Ajax状态码发生变化时将自动触发该事件
这个事件要写在send()方法的前面


两种获取服务器端响应方式的区别

  • onload事件 onreadystatechange事件
  • onload不兼容ie低版本 onreadystatechange可以
  • onload不需要判断ajax状态码 onreadystatechange需要
  • onload被调用一次 onreadystatechange被调用多次

低版本ie浏览器的缓存问题

在请求地址不发生变化的情况下,只有第一次请求会真正发送到服务器端,后续的请求都会从浏览器的缓存中获取结果,及时服务器端的数据更新了,客户端依然拿到的是缓存中的旧数据

解决方案
在请求地址的后面加请求参数,保证每一次请求中的请求参数的值不相同


ajax错误处理

  1. 网络通畅,服务器端能接受到请求,服务器端返回的结果不是预期结果
    xhr.status 获取http状态码

  2. 404找不到

  3. 500 服务器端错误

  4. 网络中断 请求无法发生
    会触发xhr下面的onerror事件
    xhr.onerror=function(){}


原生Ajax封装

代码

function ajax(options) {

  //存储默认值
  var defaults = {
    type: 'get',
    url: '',
    data: {},
    header: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    success: function(){},
    error:function(){}
  }

  //对象覆盖 直接修改原对象
  Object.assign(defaults,options);

  //创建ajax对象
  var xhr = new XMLHttpRequest();

  var params = '';

  //用户存入对象数据的话就进行遍历 并将它存为字符串
    for (var key in defaults.data) {
      params += key + '=' + defaults.data[key] + '&';
    }

    //将字符串最后的一个&去掉
    params = params.slice(0, params.length - 1);

  //判断用户传入的请求类型
  if (defaults.type == 'get') {

    //get  拼接字符串
    defaults.url = defaults.url + '?' + params;
  }

  //在open方法中传入请求类型,和请求地址
  xhr.open(defaults.type, defaults.url);
  if (defaults.type == 'post') {

    //get

    //用户希望的向服务器端请求的参数类型
    var contentType = defaults.header['Content-Type'];

    //设置请求参数格式的类型
    xhr.setRequestHeader('Content-Type', contentType);

    // var contentType = xhr.getResponseHeader('Content-Type');
    console.log(contentType)
    if (contentType == 'application/json') {
      console.log(contentType);

      //将对象格式转为对选哪个字符串  并传递
      xhr.send(JSON.stringify(defaults.data));
    } else {

      //发送请求
      console.log(params)
      xhr.send(params);
    }
  } else {
    xhr.send();
  }
  xhr.onload = function () {

    //获取响应头的数据
    let getContentType = xhr.getResponseHeader('Content-Type');

    //服务器端返回的数据
    var responseText = xhr.responseText;

    //判断是否包含application/json
    if (getContentType.includes('application/json')) {

      //从json字符串转换为json数据
      responseText = JSON.parse(responseText);

      console.log(responseText);
    }
    if (xhr.status == 200) {

      //传入xhr对象是为了查看更多的信息
      defaults.success(responseText, xhr);

    } else {

      defaults.error(responseText, xhr);

    }
  }
}
var testObj = {

  url: 'http://localhost:3000/frist',

  success: function (response) {
    console.log('success');
    console.log(response);
  },
};

ajax(testObj);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值