原生AJAX

HTML页面使用AJAX

  • 创建对象

    • const xhr = new XMLHttpRequest()
  • 初始化,设置请求方法和url,设置请求头类型

    • xhr.open(请求方式,url)
    • setRequestHeader(类型,字段)
  • 发送(请求体)

    • xhr.send()
  • 事件绑定,处理服务端返回结果

    xhr.onreadystatechange = function(){
        //判断状态与响应状态码
        if(xhr.readyState === 4){
            if(xhr.status >= 200 && xhr.status < 300){
                处理结果,返回到页面显示
            }
        }
    }
    

+express框架的js文件

4.1. GET

Get.html

  • url中?分隔 加参数名和值,多个参数之间用&
    • http://127.0.0.1:8000/server?a=100&b=200&c=300
  • onreadystatechange
    • on 相当于when,当。。。时候
    • readystate是xhr对象中的属性,表示状态(该函数会被触发四次,该一个值触发一次,间隔触发0-1,1-2,2-3,3-4)
      • 0:未初始化
      • 1:open方法调用完毕
      • 2:send方法调用完毕
      • 3:服务器返回部分结果
      • 4:服务器返回所有结果
    • change 改变
  • 状态为4,处理服务器返回结果
    • xhr.readystate === 4
  • 判断响应状态码
    • 200(2XX成功)
    • 404 请求的资源(网页等)不存在
    • 403 服务器理解请求客户端的请求,但拒绝执行此请求
    • 401 请求要求用户的身份认证
    • 500 内部服务器错误
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>AJAX GET请求</title>
  <style>
    #result {
      width: 360px;
      height: 200px;
      border: 2px solid #90EE90;
    }
  </style>
</head>

<body>
  <!-- 210321 -->
  <!-- 需求:点击按钮向服务端发送请求,结果返回客户端div中显示,页面不刷新 -->
  <button>点击发送请求</button>
  <div id="result"></div>
  <script>
    const btn = document.getElementsByTagName("button")[0];
    const result = document.getElementById("result");
    btn.onclick = function () {
      // AJAX操作,四步
      //1、创建对象
      const xhr = new XMLHttpRequest();
      //2、初始化,设置请求方法和url
      //用?分割加参数名和值,多个参数之间用&
      xhr.open('GET', 'http://127.0.0.1:8000/server?a=100&b=200&c=300');
      //3、发送
      xhr.send();
      //4、事件绑定 处理服务端返回的结果
      //on  when当。。。时候
      /* readystate 是xhr对象中的属性,表示状态:
      0(未初始化) 
      1(open方法调用完毕) 
      2(send方法调用完毕) 
      3(服务端返回部分结果)
      4(服务端返回所有结果)
      触发四次,改一个值触发一次0-1(间隔是触发)*/
      //change 改变
      xhr.onreadystatechange = function () {
        //在状态为4的时候,处理服务器返回结果
        if (xhr.readyState === 4) {
          //判断响应状态码 200 404 403 401 500
          //2XX 成功
          if (xhr.status >= 200 && xhr.status < 300) {
            //处理结果 行 头 空行 体
            //1、响应行
            // console.log(xhr.status);//状态码
            // console.log(xhr.statusText);//状态字符串
            // console.log(xhr.getAllResponseHeaders());//所有响应头
            // console.log(xhr.response);//响应体
            //设置result的文本
            result.innerHTML = xhr.response;
          } else {
            
          }
        }
      }
    }
  </script>
</body>

</html>

server.js

//1、引入express
const express = require('express');
//创建应用对象
const app = express();
//3、创建路由规则
//request 是对请求报文的封装
//response 时对响应报文的封装
app.get('/server', (request, response) => {
	//设置响应头 设置允许跨域
	response.setHeader('Access-Control-Allow-Origin', '*')
	//设置响应体
	response.send('HELLO AJAX GET -2');
});
//4、监听端口启动服务
app.listen(8000, () => {
  console.log("服务已经启动,8000端口监听中。。。。");
})

4.2. POST

post.html

  • 设置请求头内容的类型
    • 预定义
      • xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
    • 自定义
      • xhr.setRequestHeader('name', 'phy')
      • 自定义,需在js文件中添加response.setHeader('Access-Contorl-Allow-Headers', '*')
  • send()中请求体的语法可以任意,常用json
    • xhr.send('a=100&b=200&c=300')
    • xhr.send('a:100&b:200&c:300')
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>AJAX POST</title>
  <style>
    #result {
      width: 360px;
      height: 200px;
      border: 2px solid #903;
    }
  </style>
</head>

<body>
  <!-- 210321 -->
  <!-- 需求:鼠标位于div上,发送请求 -->
  <div id="result"></div>
  <script>
    //获取元素对象
    const result = document.getElementById("result");
    //绑定事件
    result.addEventListener("mousemove", function () {
      //1、创建对象
      const xhr = new XMLHttpRequest();
      //2、初始化,设置类型与URL
      xhr.open('POST', 'http://127.0.0.1:8000/server');
      //设置请求头内容的类型Content-Type,
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');//预定义
      xhr.setRequestHeader('name', 'phy'); //可以自定义,自定义会报错,解决在.js文件中添加	response.setHeader('Access-Contorl-Allow-Headers','*');
      //3、发送 请求体的语法可以任意与固定写法//最多、json
      //xhr.send();
      xhr.send('a=100&b=200&c=300');
      // xhr.send('a:100&a:200&c:300');
      //4、事件绑定
      xhr.onreadystatechange = function () {
        //判断
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            //处理服务端返回的结果
            result.innerHTML = xhr.response;
          }
        }
      }
    })
  </script>
</body>

</html>

server.js->post路由规则

//all可以接收任意类型的请求
app.all('/server', (request, response) => {
	//设置响应头 设置允许跨域
	response.setHeader('Access-Control-Allow-Origin', '*');
	response.setHeader('Access-Contorl-Allow-Headers', '*');
	//设置响应体
	response.send('HELLO AJAX POST');
});

4.3. JSON

json.html

  • 当接收响应数据是字符串时
    • ①:设置响应体数据类型,自动转json格式
      • xhr.responseType='json'
    • ②:手动转换
      • let data = JSON.parse(xhr.response)
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>JSON响应</title>
  <style>
    #result {
      width: 200px;
      height: 100px;
      border: 1px solid #FF69B4;
    }
  </style>
</head>

<body>
  <!-- 200322 -->
  <div id="result"></div>
  <script>
    window.onkeydown = function () {
      const result = document.getElementById("result");
      //发送请求
      const xhr = new XMLHttpRequest();
      //设置响应体数据的类型 //自动转换json格式
      xhr.responseType = 'json';
      //初始化
      xhr.open('GET', 'http://127.0.0.1:8000/json-server');
      //发送
      xhr.send();
      //事件绑定
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
              //服务器传递过来的数据是字符串,需要转换数据类型
            //手动对数据转换 -->Object
            //let data = JSON.parse(xhr.response);//服务器传过来的是字符串
            //console.log(data);
            //result.innerHTML = data.name;
            //当接收响应体数据是字符串是,设置响应体数据的类型( xhr.responseType = 'json';) ,自动转换json格式
            console.log(xhr.response);
            result.innerHTML = xhr.response.name;
          }
        }
      }

    }
  </script>
</body>

</html>

server.js

  • 对象转字符串
    • JSON.stringfy()
app.all('/json-server', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*');
  response.setHeader('Access-Contorl-Allow-Headers', '*');
  //响应一个数据
  const data = {
    name: 'phy'
  };
  //对对象进行字符串转换
  let str = JSON.stringify(data);
  //设置响应体 send方法只接收字符串与buffer(存储二进制数据)
  response.send(str);
});

4.4. IE缓存问题

.html

  • 设置每次请求的url不一致即可解决IE缓存问题
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>IE缓存问题</title>
  <style>
    #result {
      width: 360px;
      height: 200px;
      border: 2px solid #258;
    }
  </style>
</head>

<body>
  <!-- 210322 -->
  <button>点击发送请求</button>
  <div id="result"></div>
  <script>
    //获取元素对象
    const btn = document.getElementsByTagName("button")[0];
    const result = document.querySelector("#result");
    //绑定事件
    btn.addEventListener("click", function () {
      const xhr = new XMLHttpRequest();
      //解决方法  每次生成的url不一样
      xhr.open('GET', 'http://127.0.0.1:8000/ie?t=' + Date.now());
      xhr.send();
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            result.innerHTML = xhr.response;
          }
        }
      }
    })
  </script>
</body>

</html>

server.js

//针对IE缓存的
app.get('/ie', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  //设置响应体
  response.send('HELLO IE -5');
});

4.5. 请求超时与网络异常

.html

  • 超时设置
    • xhr.timeout = 2000
  • 超时回调
    • xhr.ontimeout
  • 设置浏览器没有网
    • chrome中network下选中online->offline
  • 网络异常回调
    • xhr.onerror
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>请求超时与网络异常</title>
  <style>
    #result {
      width: 360px;
      height: 200px;
      border: 2px solid #90b;
    }
  </style>
</head>

<body>
  <!-- 210322 -->
  <button>点击发送请求</button>
  <div id="result"></div>
  <script>
    //获取元素对象
    const btn = document.getElementsByTagName("button")[0];
    const result = document.querySelector("#result");
    //绑定事件
    btn.addEventListener("click", function () {
      const xhr = new XMLHttpRequest();
      //超时设置
      xhr.timeout = 2000;
      //超时回调
      xhr.ontimeout = function () {
        alert("网络异常,请稍后重试!");
      }
      //网络异常回调 chrome中network下选中online->offline(设置浏览器没有网)
      xhr.onerror = function () {
        alert("你的网络似乎出了一些问题!")
      }

      xhr.open('GET', 'http://127.0.0.1:8000/delay');
      xhr.send();
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          if (xhr.status >= 200 && xhr.status < 300) {
            result.innerHTML = xhr.response;
          }
        }
      }
    })
  </script>
</body>

</html>

server.js

//延时响应
app.all('/delay', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  response.setHeader('Access-Control-Allow-Headers', '*')
  setTimeout(() => {
    response.send('延时响应');
  }, 3000)
});

4.6. 取消请求与请求重复发送问题

.html

  • 请求重复发送问题:相同的多个请求,会将前面的请求删掉
  • 1、创建一个标识isSending = false,判断请求是否正在发送,是取消该请求,创建一个新的请求
  • 2、创建的新请求,将标识赋值true
  • 3、请求成功响应,标识赋值false
  • 4、取消请求xhr.abort()
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>取消请求与请求重复发送问题</title>
</head>

<body>
  <button>点击发送</button>
  <button>点击取消</button>
  <script>
    //获取元素对象
    const btns = document.querySelectorAll('button');
    let xhr = null;//不能用const,值一变就会报错
    //标识变量
    let isSending = false; //是否正在发送AJAX请求

    btns[0].onclick = function () {
      //判断标识变量
      if (isSending)
        //如果正在发送,则取消该请求,创建一个新的请求
        xhr.abort();
      xhr = new XMLHttpRequest();
      //修改 标识变量的值
      isSending = true;
      xhr.open('GET', 'http://127.0.0.1:8000/delay');
      xhr.send();
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4) {
          //修改标识变量
          isSending = false;
        }
      }
    }

    //取消abort
    btns[1].onclick = function () {
      xhr.abort();
    }

	//请求重复发送问题:相同的多个请求,将前面的请求删掉

  </script>
</body>

</html>

server.js

//延时响应
app.all('/delay', (request, response) => {
  //设置响应头 设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*')
  response.setHeader('Access-Control-Allow-Headers', '*')
  setTimeout(() => {
    response.send('延时响应');
  }, 3000)
});
posted @ 2021-07-14 15:05  STRIVE-PHY  阅读(127)  评论(0编辑  收藏  举报