fetch

提供了一个获取资源的接口,更强大和灵活的功能集

Response对象

Response.clone()

创建一个Response对象的克隆

Response.json()

读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为JSON格式的promise对象

Response.text()

读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为USVString格式的promise对象

基本使用

  • 无论请求成功与否,它都返回一个 Promise 对象
  • json()返回响应的json对象
  • res.text()返回响应的字符串

get

    function onGet() {
      fetch("/getData", {
        method: "get",
      }).then((res) => {
        console.log(res);
        return res.json();
      }).then((data) => {
        console.log(data)
      })
    }

post

    function onPost() {
      let data = {
        name: "lc",
        age: 18
      }
      fetch("/postData", {
        method: "post",
        body: JSON.stringify(data),
        headers: {
          "content-type": "application/json"
        }
      }).then((res) => {
        console.log(res);
        return res.json();
      }).then((data) => {
        console.log(data)
      })
    }

在这里插入图片描述

Headers对象

可以通过 Headers() 构造函数来创建一个自己的 headers 对象。
第一种方式

var myHeaders = new Headers();
myHeaders.append("Content-Type", "text/plain");
myHeaders.append("Content-Length", content.length.toString());
myHeaders.append("X-Custom-Header", "ProcessThisImmediately")

第二种

myHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": content.length.toString(),
  "X-Custom-Header": "ProcessThisImmediately",
});

Request对象

外部狗仔request请求格式

    function onPost() {
      let data = {
        name: "lc",
        age: 18
      }
      const headers = new Headers();
      headers.append("content-type", "application/json");
      const request = new Request("/postData", {
        method: "post",
        body: JSON.stringify(data),
        headers,
      })

      fetch(request).then((res) => {
        console.log(res);
        return res.json(data);
      }).then((data) => {
        console.log(data)
      })
    }

Fetch 与 XMLHttpRequest 的差异

  • fetch不能监控进度

  • fetch兼容性不好

axios

函数调用

get 数据是params格式

    function onGet() {
      let data = {
        name: "lc",
        age: 18
      }
      axios({
        method: "get",
        url: "/getData",
        params: {
          ...data
        }
      }).then((res) => {
        console.log(res)
        console.log(res.data)
      })
    }

post 数据时 data形式

    function onPost() {
      let data = {
        name: "lc",
        age: 18
      }
      axios({
        method: "post",
        url: "/postData",
        data: {
          ...data
        }
      }).then((res) => {
        console.log(res)
        console.log(res.data)
      })
    }

对象调用

    function onGet() {
      let data = {
        name: "lc",
        age: 18
      }
      axios.get("/getData", {
        params: {
          ...data
        },
      }).then((res => {
        console.log(res.data)
      }))
    }
    function onPost() {
      let data = {
        name: "lc",
        age: 18
      }
      axios.post("/postData", {
        data: {
          ...data
        },
      }).then((res => {
        console.log(res.data)
      }))
    }

拦截器

简单的说就是可以使用拦截器对请求或者拦截做出统一批量再处理
比如添加头字段、对用户密码进行验证等

请求拦截

    axios.interceptors.request.use((config) => {
      console.log("request 111");
      return config;
    });

    axios.interceptors.request.use((config) => {
      console.log("request 222");
      console.log(config);
      return config;
    });

执行顺序
在这里插入图片描述

响应拦截器

    axios.interceptors.response.use((response) => {
      console.log("response 111");
      return response;
    });

    axios.interceptors.response.use((response) => {
      console.log("response 222");
      console.log(response);
      return response;
    });

在这里插入图片描述

拦截器结合jwt验证用户信息

使用koaJwt的问题

使用koajwt的时候,第一次登陆就会返回401,因为第一次登陆并未设置token,所以需要跳过login路由的鉴权

app.use(koaJwt({ secret }).unless({ path: [/^\/login/] }));

第一次登陆成功设置token

router.post("/login", (ctx) => {
  // 先验证账号和密码对不对
  const { username, passwd } = ctx.request.body;

  if (username === "h" && passwd === "123") {
    const token = jwt.sign(
      {
        uId: 1,
      },
      secret,
      {
        expiresIn: "2h",
      }
    );

    ctx.body = {
      state: 1,
      msg: "登录成功",
      data: {
        token,
      },
    };
  } else {
    ctx.body = {
      state: 1,
      msg: "账号或者密码不对",
    };
  }
});

前端将返回的token存入localstorage

loginBtn.addEventListener("click", async () => {
  const res = await axios.post("/login", {
    username: "h",
    passwd: "123",
  });
  console.log(res.data);

  const token = res.data.data.token;
  localStorage.setItem("token", "Bearer " + token);
});

封装axios

坏境切换 baseURL,请求超时时间
// 生产坏境的前缀
// 生产坏境  localhost:8081
// 开发坏境  localhost:8080

const DEV = "dev";
const PROD = "prod";
const env = DEV;

// axios.get("/getData")
// http://localhost:8080/getData
const myAxios = axios.create({
  baseURL: env === DEV ? "http://localhost:8080" : "http://localhost:8081",
  timeout: 4000,	// 请求时间大于4s报错
});

设置koajwt跳过login路由鉴权

app.use(koaJwt({ secret }).unless({ path: [/^\/login/] }));

请求拦截器:给请求添加上token

// 结合 jwt
// 请求拦截器
myAxios.interceptors.request.use((config) => {
  const token = localStorage.getItem("token");
  console.log(token);
  if (token) {
    config.headers.Authorization = token;
  }
  return config;
});

export default myAxios;

在这里插入图片描述

响应拦截器:统一处理错误请求

故意设置个延迟2s,然后后端定时3s响应,然后报错

// 生产坏境的前缀
// 生产坏境  localhost:8081
// 开发坏境  localhost:8080

const DEV = "dev";
const PROD = "prod";
const env = DEV;

// axios.get("/getData")
// http://localhost:8080/getData
const myAxios = axios.create({
  baseURL: env === DEV ? "http://localhost:8080" : "http://localhost:8081",
  timeout: 2000,
});

// 统一处理错误
myAxios.interceptors.response.use(
  (res) => {
    return res;
  },
  (err) => {
    console.log(err.response);
    if (err.response.status === 401) {
      alert("please go to login");
    }

    return Promise.reject(err);
  }
);

export default myAxios;

比如token值清空后的错误处理

myAxios.interceptors.response.use(
  (res) => {
    return res;
  },
  (err) => {
    console.log(err.response);
    if (err.response.status === 401) {
      alert("please go to login");
    }

    return Promise.reject(err);
  }
);
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐