HTTP总结/ xhr封装axios /取消请求

HTTP

  • 超文本传输协议:规定互联网客户端、服务器和服务器之间的通信规则

  • 通信的内容,称为报文

    • 请求报文
    • 响应报文
  • 报文组成:

    • 报文首行
    • 报文头
    • 空行
    • 报文主体
  • 请求报文

    • 请求首行
      • 请求方式 GET(查) POST(增) PUT(全部改) PATCH(部分改) DELETE(删)
      • 请求地址 可能携带查询字符串参数(querystring、params)?key=value&key=value
    • 请求头
      • content-type 请求主体的类型
    • 请求主体
      • POST PUT PATCH请求方式的请求参数
  • 请求体参数类型

    • content-type: application/json json格式的参数 {“name”: “jack”}
    • content-type: x-www-form-urlencoded form表单格式的参数 key=value&key=value
  • 响应报文

    • 响应首行
      • 响应状态码status
        • 1xx 代表请求还未完成,需要进一步处理
        • 2xx 代表请求成功 200
        • 3xx 代表请求重定向
          • 301 永久重定向
          • 302 临时重定向
          • 304 走协商缓存
        • 4xx 代表客户端错误
          • 401 未授权
          • 403 禁止
          • 404 资源找不到
        • 5xx 代表服务器错误
          • 500

原生axios

 // 1.创建xhr对象
 const xhr = new XMLHttpRequest();
 // 2.给xhr绑定onreadystatechange事件
 xhr.onreadystatechange = function () {
   if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status <= 299) {
     console.log(xhr.responseText);
     console.log(xhr)
   }
 };
 // 3.设置请求信息
 xhr.open("GET", "http://localhost:3000/posts");
 // 4.发送请求
 xhr.send();

xhr封装axios

function axios({
  method, // 请求方式
  url, // 请求地址
  data, // 请求体参数 body
  params, // querystring 查询字符串参数
}) {
  return new Promise((resolve, reject) => {
    method = method.toUpperCase();
    // 1. 创建xhr对象
    const xhr = new XMLHttpRequest();
    // 2. 绑定onreadystatechange事件
    // 当readystate发生变化时触发的事件
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        // 响应返回了(但是成功、失败不知道)
        if (xhr.status >= 200 && xhr.status < 300) {
          // 响应成功
          const response = {
            request: xhr,
            status: xhr.status,
            data: JSON.parse(xhr.responseText),
          };
          resolve(response);
        } else {
          // 响应失败
          console.log("error", xhr);
          reject("error");
        }
      }
    };
    /*
      通常情况下:
        GET、DELETE请求,只会有查询字符串参数
        POST、PUT、PATCH请求,既可以有请求体参数,也可以有查询字符串参数
      params: { name: 'jack', age: 18 } 
        --> url?name=jack&age=18
    */
    let qs = "";
    if (params) {
      // 提取params中所有属性名成为一个数组
      // ['name', 'age']
      qs = Object.keys(params)
        .reduce((p, key) => {
          const value = params[key];
          return p + `${key}=${value}&`;
        }, "?")
        .slice(0, -1);
    }

    // 3. 设置请求信息(请求地址、请求方法。。。)
    xhr.open(method, url + qs);

    let body = "";
    if (
      (method === "POST" || method === "PUT" || method === "PATCH") &&
      data
    ) {
      // 设置请求头
      xhr.setRequestHeader("content-type", "application/json");
      body = JSON.stringify(data);
    }
    // 4. 发送请求
    xhr.send(body);
  });
}

btn1.onclick = function () {
  // 发送GET请求

  axios({
    method: "GET",
    url: "http://localhost:3000/comments",
  })
    .then((value) => {
      // 200-299
      console.log("value", value);
    })
    .catch((reason) => {
      console.log("reason", reason);
    });
};

btn2.onclick = function () {
  // 发送POST请求

  axios({
    method: "POST",
    url: "http://localhost:3000/comments",
    data: {
      // 请求体参数 body
      body: "i like laoluo",
      postId: 3,
    },
  })
    .then((value) => {
      // 200-299
      console.log("value", value);
    })
    .catch((reason) => {
      console.log("reason", reason);
    });
};
</script>

取消方式一

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="btn">发送请求</button>
    <button id="btn1">取消请求</button>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>

    <script>
      const CancelToken = axios.CancelToken;
      const source = CancelToken.source();

      btn.onclick = function () {
        axios({
          url: "http://localhost:3000/comments",
          cancelToken: source.token,
        })
          .then((result) => {
            console.log("resule", result);
          })
          .catch((err) => {
            console.log("err", err);
          });
      };

      btn1.onclick = function () {
        // 取消请求
        source.cancel("取消请求了");
      };
    </script>
  </body>
</html>

取消方式二(常用)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="btn">发送请求</button>
    <button id="btn1">取消请求</button>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>

    <script>
      let cancel = null;
      btn.onclick = function () {
        axios({
          url: "http://localhost:3000/comments",
          cancelToken: new axios.CancelToken(function (c) {
            cancel = c;
          }),
        })
          .then((result) => {
            console.log("resule", result);
          })
          .catch((err) => {
            if (axios.isCancel(err)) {
              console.log("错误是取消请求导致的", err);
              return;
            }
            console.log("err", err);
          });
      };

      btn1.onclick = function () {
        // 取消请求
        cancel("取消请求了");
      };
    </script>
  </body>
</html>

取消方式三

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="btn">发送请求</button>
    <button id="btn1">取消请求</button>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
    <script>
      let cancel = null;
      btn.onclick = function () {
        axios({
          url: "http://localhost:3000/comments",
          cancelToken: new axios.CancelToken(function (c) {
            cancel = c;
          }),
        })
          .then((result) => {
            console.log(result);
          })
          .catch((err) => {
            console.log(err);
          });
      };

      btn1.onclick = function () {
        cancel("quxiaoqingqiu ");
      };
    </script>
  </body>
</html>

server

const express = require("express");
const app = express();

app.get("/comments", (req, res) => {
  // 处理跨域 jsop cors
  res.set("Access-Control-Allow-Origin", "*");

  // 让服务器三秒以后再返回响应
  setTimeout(() => {
    res.json({
      code: 10000,
      data: [
        {
          id: 1,
          title: "劳斯宾利法拉利",
        },
      ],
    });
  }, 3000);
});

app.listen(3000,"localhost",(err)=>{
    if (err) {
        console.log("err",err);
        return
    }
    console.log("服务器启动成功,请访问http://localhost:3000");
})
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 像素格子 设计师:CSDN官方博客 返回首页