ajax

94 阅读5分钟

一.相关点

URL --- 协议名称 + 主句名称 + 端口号 + 路径 + 文件 + 查询所需的字符串

    http:// 百度 .com 8 /aa /bb /c.txt ? a=1&b=2
  1. http --- 超文本传输协议. 本质就是客户端和服务器之间沟通的交流规则.
  2. http请求 (Request): 由客户端向服务器发出请求.
  • 请求行: 请求方法 get pust put delete
  • 请求头: text/plain、application/x-www-form-urlencoded、 application/json、mutipul/form-data
  • 请求体: 传输给服务器的数据, 只有post请求和put请求才有请求体, get没有请求体
  1. http响应 (Response): 由服务器给出响应
  • 响应行
  • 响应头
  • 响应体

QQ截图20240416192926.png

二. 原生AJAX

0. ajax的起步

搭建一下后端,创建一个文件夹,

QQ截图20240416202141.png

生成项目的配置文件:

QQ截图20240416202258.png

安装依赖

"dependencies": {
    "body-parser": "^1.20.0",
    "express": "^4.18.1",
    "multer": "^1.4.5-lts.1"
}

QQ截图20240416203043.png

创建一台服务器,如下

const express = require("express")
const path = require("path")

// 创建 express 实例
const app = express();


app.get("/demo01",(req,res)=>{
    res.sendFile(path.join(__dirname,"../client","01-ajax的基本使用.html"))
})

// 当访问getData路径时,服务器响应 hello ajax 0.2
// 服务器代码变了,需要重启服务器
app.get('/getData', (req, res) => {
    console.log('接收到请求');
    res.send('hello ajax ' + Math.random());
});

app.listen(3000,()=>{
    console.log('服务器启动了,端口是3000');
})

写入前端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>ajax的基本使用</h1>
    <hr>
    <button id="btn">点击发请求</button>

    <script>
        const btn = document.querySelector('#btn');

        btn.onclick = () => {
            // 1) 创建一个xhr对象
            const xhr = new XMLHttpRequest();

            // 2) 监听成功的响应(服务器成功响应了数据,就会触发load事件)
            xhr.onload = ()=>{
                console.log('成功接收到后端的响应!');
                // responseText 得到服务器给的响应
                console.log(xhr.responseText)
            }

            // 3) 设置请求
            //    第一个参数 请求方式   get  post  put  delete  head ....
            //    第二个参数 请求URL  http://127.0.0.1:3000/getData
            //               /getData   协议  IP  端口  不写  表示向当前页面所在的服务器发请求
            //    第三个参数 是否异步,默认异步
            xhr.open("get","http://127.0.0.1:3000/getData")

            // 4) 发出请求
            //      发请求时,可以给服务器传递参数  send(请求体)
            xhr.send();
        }
    </script>
</body>
</html>

1. 原生ajax的经典四步

后端代码

const Koa = require("koa");
const cors = require("koa2-cors");
const logger = require("koa-logger");
const Router = require("@koa/router"); //路由
const koaBody = require("koa-body");
const app = new Koa();
const router = new Router(); //路由

app.use(cors());
app.use(logger());
app.use(koaBody());

// 写了一个接口  请求方式是get  请求的api是/getData
// 请求返回的状态码是200  返回的结果是helloajax
router.get("/getData", async (ctx, next) => {

  // 表示响应的状态码是200
  ctx.status = 200;
  
  // 响应给我们的一个对象
  ctx.body = "hello Ajax";
});

app.use(router.routes());
router.allowedMethods();

app.listen(3001, () => {
  console.log("服务器跑起来了");
});

前端代码

    // 第一步:创建网络请求的AJAX对象(使用XMLHttpRequest)
    let xhr = new XMLHttpRequest()
    console.log(xhr);//AJAX对象
    console.log(xhr.readyState);  //状态--0

    // 第二步:监听XMLHttpRequest对象状态的变化,或者监听onload事件(请求完成时触发)
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            // response就是响应
            console.log(xhr.response);
        }   
    }
    // 第三步:配置网络请求(通过open方法)
    xhr.open('get', 'http://127.0.0.1:3001/getData')

    // 第四步:发送send网络请求
    xhr.send()

3. xhr对象的load事件

当服务器把数据响应给ajax的时候 会触发load事件

<script>
        // 当服务器把数据响应给ajax的时候 会触发load事件
        xhr.onload = function () {
            console.log(xhr.response);
        }

        xhr.open('get', 'http://127.0.0.1:3001/getData')
        xhr.send()
</script>

4. 后端响应的json数据

若后端响应一个JSON数据,则设置一个响应头,告诉客户端,响应的数据类型 写入后端

// 导入模块
const path = require('path');
const express = require('express');

// 创建 express 实例
const app = express();

app.get("/",(req,res)=>{
    res.sendFile(path.join(__dirname,"../client","index.html"))
})

app.get('/getData', (req, res) => {
    console.log('接收到请求');
    const stus = [
        {id:"01",name:"malu",age:18,score:88},
        {id:"02",name:"wc",age:13,score:23},
        {id:"03",name:"xq",age:16,score:44},
        {id:"04",name:"xx",age:10,score:55},
    ]
    const stusStr = JSON.stringify(stus)
    // 告诉客户端,响应的是JSON数据
    res.setHeader("Content-Type", "application/json;charset=utf-8");
    res.send(stusStr);
});

app.listen(3000,()=>{
    console.log('服务器启动了,端口是3000');
})

写入前端

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <button id="btn">点我发请求</button>
</head>

<body>
    <script>
        const xhr = new XMLHttpRequest();

       // 设置期望的响应数据的数据类型,期望服务器响应json
        xhr.responseType = "json";
        xhr.onload = function () {
            // xhr.response得到服务器响应的JSON数据 
            console.log(xhr.response);
        }

        const btn = document.querySelector("#btn");
        btn.onclick = () => {
            // 请求同一个url,第一次不走缓存,
            // 从第二次开始,就可能走缓存,304表示走的缓存
            // 不想走缓冲,需要让每次请求的url不一样
            // 添加随机数 Math.random()
            xhr.open("get", "/getData?random="+Math.random())
            xhr.send(null);
        }

    </script>
</body>

</html>

其中后端响应的json数据有两种方式,第二种如下

 <script>
        const xhr = new XMLHttpRequest();
        xhr.onload = function () {
        console.log(JSON.parse(xhr.responseText));   
        }  
</script>

6. get传参

7. post传参

8. post传递json数据

9. post传递formData数据

10. 超时处理和取消请求

写入后端

// 导入模块
const path = require('path');
const express = require('express');

// 创建 express 实例
const app = express();

app.get("/",(req,res)=>{
    res.sendFile(path.join(__dirname,"../client","index.html"))
})

app.get('/getData', (req, res) => {
    console.log('接收到请求');
    const timeout = Math.floor(Math.random()*10) * 1000

    const stus = [
        {id:"01",name:"malu",age:18,score:88},
        {id:"02",name:"wc",age:13,score:23},
        {id:"03",name:"xq",age:16,score:44},
        {id:"04",name:"xx",age:10,score:55},
    ]
    const stusStr = JSON.stringify(stus)
    // 告诉客户端,响应的是JSON数据
    res.setHeader("Content-Type", "application/json;charset=utf-8");
    setTimeout(()=>{
        res.send(stusStr);
    },timeout)
});

app.listen(3000,()=>{
    console.log('服务器启动了,端口是3000');
})

写入前端

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <button id="btn">点我发请求</button>
    <button id="btn2">手动取消请求</button>
</head>

<body>
    <script>
        const xhr = new XMLHttpRequest();
        // 进行格式转换
        xhr.responseType = "json";

        xhr.onload = function () {
            console.log(xhr.response);
        }


        // 设置超时时间  5s
        // 如果时间到了,数据还没有回来,会自动取消请求
        xhr.timeout = 5000; 

        const btn = document.querySelector("#btn");
        btn.onclick = () => {
            xhr.open("get", "/getData?xx="+Date.now())
            xhr.send(null);
        }
        
        
        // 手动取消
        const btn2 = document.querySelector("#btn2");
        btn2.onclick = () => {
          xhr.abort(); // 取消请求~
        }

    </script>
</body>

</html>

10.总结

  1. 经典四步:
  • 第一步 创建网络请求的Ajax对象
  • 第二步 监听XMLHttpRequest对象状态变化(或load事件)
  • 第三步 配置网络请求
  • 第四步 发送网络请求

2.后端响应的xml事件

  • 通过network查看 响应的数据类型是:Content-Type:application/xml
xhr.onload = function () {
        console.log(xhr.response);
        console.log(xhr.responseXML);
    }
  1. get传参(两种方式)
    let xhr = new XMLHttpRequest()

    xhr.onload = function () {
        console.log(xhr.response)
    }

    // get传参的第一种方式: 通过query传参
    // xhr.open('get', 'http://127.0.0.1:3001/get?name=zhangsan&&address=zz')
     ----------------------------------------------------
    // get传参的第二种方式: 通过params传参
    // 通过params传参 并没有payload(荷载)选项
    xhr.open('get', 'http://127.0.0.1:3001/get/zhangsan/18/zz')

    xhr.send()
  1. post传参
  • 需要把参数放在请求体中 ----- send('请求体')
  • 但是 在开发中,需要传递的格式有:
    • 1)x-www-form-urlencode
    • 2)formdata
    • 3)json