axios/fetch/ajax面试应用宝典-跨域请求携带cookie

引言

本文将融百家之言,成xhr家族之唱,依次介绍xhr嫡次子axios(最得前端厚爱),ajax为xhr家族嫡长子(资历最长),老三fetch(网络请求新秀)为义子(原理不是基于xhr的,基于promise),携带cookie发起请求实例以及面试题带记。

一、ajax/axios/fetch简介:

1.ajax简介
姓名:ajax
职业:基于 promise 的网络请求(可以直接使用)
工作地点:浏览器和 node.js
生产工艺:核心原生XHR,外挂Promise,符合最新的ES规范

2.axios简介
姓名:axios
职业:基于 promise 的网络请求 (使用时需要下载安装)
工作地点:浏览器和 node.js
生产工艺:核心原生XHR,外挂Promise,符合最新的ES规范
技能特长:
(1)在浏览器创建 XMLHttpRequests,在 node.js 创建 http 请求;
(2)支持 Promise API拦截请求和响应转换请求和响应数据,取消请求自动转换JSON数据客户端支持防御XSRF;
(3)可以发起jsonp请求,默认不携带cookie

3.fetch简介
姓名:fetch
职业:基于 promise 的网络请求
工作地点:浏览器
生产工艺:核心基于Promise,非xhr
技能特长:
(1)只对网络请求报错,对于错误状态码400/500都会当作成功的请求,只有网络出问题才会reject;
(2)可以配合async/await一起请求,避免ajax/axios请求不成功,影响后面代码执行;
(3)默认不会带cookie,需要添加配置项: fetch(url, {credentials: ‘include’});
(4)fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费;
(5)fetch没有办法原生监测请求的进度,而XHR可以;
(6)fetch的第12个.then拿到接口返回的数据
参考文章:fetch与axios、浏览器内多个标签页面通信及安全问题

二、axios案例分享

1.axios请求携带cookie示例

axios的请求配置默认是不携带 cookie 信息的,如何使得ajax请求携带cookie呢?

对于前端而言,只需要将axios的对象属性 withCredentials属性设为 true,
注意,axios的headers属性设为空对象,不然接口会报cors的错误哦

后端同学请注意,前端开启axios的 withCredentials属性后,

(1)服务端的headers属性中的Access-Control-Allow-Origin将不能设为’*';

(2)服务端的headers属性中的Access-Control-Allow-Credentials需设为true

注意,这种前端、后端配合的axios携带cookie的请求方式可以解决——跨域问题哦!

开启withCredentials属性,携带cookie代码示例

1.1局部封装:axios开启withCredentials属性

import axios from 'axios';
import qs from 'qs'
// 对post请求二次封装
function cookiePost(url, params) {
  return new Promise((resolve, reject) => {
    let query = {
      ...params,
    }
    axios({
      url: url,
      headers: {},
      method: "get",
      data: qs.stringify(query),
      withCredentials: true,
      timeout: 30000
    })
      .then((res) => {
        let data = res.data;
        resolve(data);
      })
      .catch((err) => {
        reject(err.data);
      });;
  });
}
function ckGet(url, params) {
  return new Promise((resolve, reject) => {
    axios({
      url,
      params,
      headers: {
        // "Access-Control-Allow-Origin": "*",
      },
      method: "get",
      withCredentials: true
    })
      .then((res) => {
        let data = res.data;
        resolve(data);
      })
      .catch((err) => {
        reject(err.data);
      });
  })
}
function cookieGet(url, params) {
  return new Promise((resolve, reject) => {
      let query = {
        ...params
      }
      url += qs.stringify(query)
      axios
        .get(url, { withCredentials: true })
        .then((res) => {
          let data = res.data;
          resolve(data);
        })
        .catch((err) => {
          reject(err.data);
        });
    })
}
//可以将封装好的axios挂载在window上对外暴露
window.Axios = {
  cookiePost,
  cookieGet,
  ckGet
};

项目中使用封装好的cookiePost示例

export function post(params) {
  const url = ``;
  return Axios.cookiePost(url, {...params});
}

1.2全局封装:axios开启withCredentials属性

import axios from 'axios';
axios.defaults.withCredentials=true;

参考文章:axios携带cookie

1.3 fetch携带cookie方法

同axios,fetch默认不携带cookie,

  fetch(url, {
        method: 'POST',
        credentials: "include"
    }).then((response)=>response.json())
        .then((responseJsonData)=> {
        //fetch的第二个.then才能拿到数据对象
            callback && callback(responseJsonData);
        }).catch((error)=> {
            errorCallBack && errorCallBack(error);
            console.log(error);
        });

参考文章: 同源、跨域(以及ajax、fetch携带cookie)

1.4 ajax携带cookie并进行跨域请求方法

  let url = ``;
  const params={}
        let res = await $.ajax({
          url,
          type: "POST",
          dataType: "json",
          data: params,
          xhrFields: {
            withCredentials: true, // 此字段标识要跨域传数据
          },
          crossDomain: true,
        });
        console.log(res)
        

2.axios请求拦截器响应拦截器加密封装

// 请求拦截器
axios.interceptors.request.use(
  (config) => {
    return config;
  },
  (error) => {
    return Promise.error(error);
  }
);

// 响应拦截器
axios.interceptors.response.use(
  (response) => {
    if (response.status === 200) {
      return Promise.resolve(response);
    } else {
      return Promise.reject(response);
    }
  },
  // 服务器状态码不是200的情况
  (error) => {
  }
);

参考文章:1.http://zhenglinglu.cn/pages/6ec693/#_1%E3%80%81%E5%85%A8%E5%B1%80%E8%AE%BE%E7%BD%AE
2.https://blog.csdn.net/xiashiqi_blog/article/details/84979134

3.https://blog.csdn.net/lfcss/article/details/121275023

4.https://blog.csdn.net/lfcss/article/details/121275023

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值