前端开发中的ajax请求、axios封装

这篇具有很好参考价值的文章主要介绍了前端开发中的ajax请求、axios封装。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

浏览器http请求

同步 js标签跨域、url

异步ajax、websock协议

ajax是异步的技术术语,最早的api是xhr(XMLHttpRequest)

fetch es6 api

axios

封装axios(无论用requst还是axios请求都会生效)

src/utils/request.ts请求/响应拦截器封装

ts

post请求request.post(url)和 通用请求request({url,method:'post'})对象参数区别

src/utils/func.ts工具

ts

SSO(Single Sign-On)单点登录,一次登陆可访问多个相互独立的程序

正则表达式

常用字符

前/后向查找:匹配括号中的内容(不包含括号)

泛型(传参给类型)

src/api/common.ts封装请求

src/views/components二次封装请求

基础知识回顾

url参数

location属性值

同源策略

token和cookie

替换cookie(开发中模拟不同权限的用户)

A.手动

B.设置index.html 

C.浏览器扩展小程序:一键获取/设置多个

web安全

XSS跨站脚本攻击Cross-Site Scripting(登陆时执行脚本读取)

CSRF跨站请求伪造Cross-site request forgery(凭证请求)

SQL注入攻击(交表单/输域名 执行SQL命令)

DDoS攻击分布式拒绝服务 Distributed Denial of Service(请求过载)


浏览器http请求

同步 js标签跨域、url

<img src>,<link href>

异步ajax、websock协议

ajax是异步的技术术语,最早的api是xhr(XMLHttpRequest)

fetch es6 api

基于promise,简单易用 

axios

  • 同构,即同样的代码在nodejs端,浏览器端都可用
  • 在浏览器用xhr,Node.js中使用Node的内置http模块。
// 在浏览器中,根据其Content-Type头信息,自动转换数据
axios.get('/api/data').then(response => {
  // response.data 将是一个JavaScript对象
});

// 在Node.js中手动设置响应数据类型
axios.get('/api/data', { responseType: 'json' }).then(response => {
  // response.data 将是一个JavaScript对象
});
  • axios 新版本也支持了fetch
  • 第三方库都是基于原生API的,所以axios也还是基于xhr的

【JavaScript】爆肝 2 万字!一次性搞懂 Ajax、Fetch 和 Axios 的区别~ - 掘金

封装axios(无论用requst还是axios请求都会生效)

axios常用类型

src/utils/request.ts请求/响应拦截器封装

import service from 'axios'
//service是一个根据需要自行命名,通过axios库创建的HTTP请求服务实例

import { handleSSO,errorMsgTips } from '@/utils/func'
import router from '@/router/index'

// 请求拦截器
service.interceptors.request.use(
  (config: any) => {
    // 在请求头中添加XMLHttpRequest字段
    config.headers['X-Requested-With'] = 'XMLHttpRequest'
    return config
  },
  (error: any) => {
    console.log('request:', error) // 用于调试的错误信息
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  (response: { data: any; config: HttpRequestConfig }) => {
    const resData = response.data || {}
    if (resData.code === 302) {
      // 如果响应码为302,进行页面重定向到指定链接
      window.location.href = `https://www.example.com/path/to/resource.html/domain=${location.host}&req=${encodeURIComponent(location.pathname)}&protocol=https${location.hash}`
    } else if (resData.code == 0 || resData.code == 200) {
      // 如果响应码为0或200,则直接返回响应数据
      return resData
    } else if (resData.code == 4004) {//自定义响应码
      // 如果响应码为4004,说明没有权限,跳转至无权限页面
      router.push({
        path: '/notPermission'
      })
    } else {
      // 其他情况下,显示错误提示消息
      errorMsgTips(resData.message || '接口错误,请稍后重试')
    }
  },
  (error: any) => {
    if (service.isCancel(error)) {
      console.log('取消请求 error -> ', error)
      return
    }
    if (error && error.response && error.response.status === 302) {
      if (process.env.NODE_ENV === 'development') {
        // 如果是开发环境,并且错误码为302,显示替换SSO_SESSION_ID的提示
        errorMsgTips('请替换Cookies里的SSO_SESSION_ID')
        return
      } else {
        // 非开发环境下,进行单点登录重定向
        window.location.href = handleSSO('login')
      }
    } else if (error && error.stack.includes('timeout')) {
      // 如果错误信息中包含"timeout",显示接口超时错误提示
      errorMsgTips('接口超时')
      return
    } else if (error && error.stack.includes('Network')) {
      // 如果错误信息中包含"Network",显示网络异常错误提示
      errorMsgTips('网络异常')
      return
    }
    return Promise.reject(error)
  }
)

export default service

ts

import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import { handleSSO, errorMsgTips } from '@/utils/func';
import router from '@/router/index';

// 请求拦截器
axios.interceptors.request.use(
  (config: AxiosRequestConfig) => {
    // 在请求头中添加XMLHttpRequest字段
    config.headers['X-Requested-With'] = 'XMLHttpRequest';
    return config;
  },
  (error: AxiosError) => {
    console.log('request:', error); // 用于调试的错误信息
    return Promise.reject(error);
  }
);

// 响应拦截器
axios.interceptors.response.use(
  (response: AxiosResponse) => {
    const resData = response.data || {};
    if (resData.code === 302) {
      // 如果响应码为302,进行页面重定向到指定链接
      window.location.href = `https://www.example.com/path/to/resource.html/domain=${location.host}&req=${encodeURIComponent(location.pathname)}&protocol=https${location.hash}`;
    } else if (resData.code == 0 || resData.code == 200) {
      // 如果响应码为0或200,则直接返回响应数据
      return resData;
    } else if (resData.code == 4004) { //自定义响应码
      // 如果响应码为4004,说明没有权限,跳转至无权限页面
      router.push({
        path: '/notPermission'
      });
    } else {
      // 其他情况下,显示错误提示消息
      errorMsgTips(resData.message || '接口错误,请稍后重试');
    }
    return Promise.reject(resData);
  },
  (error: AxiosError) => {
    if (axios.isCancel(error)) {
      console.log('取消请求 error -> ', error);
      return;
    }
    if (error && error.response && error.response.status === 302) {
      if (process.env.NODE_ENV === 'development') {
        // 如果是开发环境,并且错误码为302,显示替换SSO_SESSION_ID的提示
        errorMsgTips('请替换Cookies里的SSO_SESSION_ID');
        return;
      } else {
        // 非开发环境下,进行单点登录重定向
        window.location.href = handleSSO('login');
      }
    } else if (error && error.stack.includes('timeout')) {
      // 如果错误信息中包含"timeout",显示接口超时错误提示
      errorMsgTips('接口超时');
      return;
    } else if (error && error.stack.includes('Network')) {
      // 如果错误信息中包含"Network",显示网络异常错误提示
      errorMsgTips('网络异常');
      return;
    }
    return Promise.reject(error);
  }
);

export default axios;

post请求request.post(url)和 通用请求request({url,method:'post'})对象参数区别

具体请求方式只能使用指定的请求方法,如 postgetput 等。

axios.post(url, data, {
  responseType: 'json' // 设置响应的数据类型为 JSON
})
  .then(response => {
    // 处理响应数据
    console.log(response.data);
  })
  .catch(error => {
    // 处理请求错误
    console.error(error);
  });

src/utils/func.ts工具

/**
 * 清除会话
 * @param
 */
function clearSession() {
  //匹配不包含空格和分号的字符,该字符后面必须跟着一个等号。这会返回一个由cookie键组成的数组。
  const keys = document.cookie.match(/[^ =;]+(?=\=)/g)
  if (keys) {
    for (let i = keys.length; i--; )
     //) 创建了一个代表时间戳 0 的 JavaScript Date 对象,并将其转换为 UTC 字符串。
     //这个时间对应于 1970 年 1 月 1 日 协调世界时 (UTC) 时间 00:00:00。
      document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
  }
  sessionStorage.clear()
  localStorage.clear()
}

/**
 * SSO登入登出
 * @param SSOtype
 * login登入
 * logout登出
 */
export function handleSSO(SSOtype: string): string {
  const hostStr = 'passport.example.com'
  clearSession()
  return `https://${hostStr}/${SSOtype}?service=` + encodeURIComponent(window.location.origin)
}



export function errorMsgTips(msg: string) {
  window.$message.error(msg)
}

ts

/**
 * 清除会话
 */
function clearSession(): void {
  const keys: string[] | null = document.cookie.match(/[^ =;]+(?=\=)/g);
  if (keys) {
    for (let i = keys.length; i--; ) {
      document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString();
    }
  }
  sessionStorage.clear();
  localStorage.clear();
}

/**
 * SSO登入登出
 * @param SSOtype
 * login 登入
 * logout 登出
 */
export function handleSSO(SSOtype: 'login' | 'logout'): string {
  const hostStr = 'passport.example.com';
  clearSession();
  return `https://${hostStr}/${SSOtype}?service=` + encodeURIComponent(window.location.origin);
}

export function errorMsgTips(msg: string): void {
  window.$message.error(msg);
}

SSO(Single Sign-On)单点登录,一次登陆可访问多个相互独立的程序

通常靠token/cookie实现

正则表达式

常用字符

·匹配除换行字符外的任何单个字符
*匹配前一个字符零或多次。例如,"zo*”与"z”或"zoo”匹配。
+匹配前一个字符一次或多次。例如,"zo+"与"zoo”匹配,但和"z”不匹配。
?匹配前一个字符零或一次。例如,"a?ve?”和"never"中的“"ve”匹配。
x|y 匹配x或y
{n}匹配n次。n是非负整数
{n,} n是一个非负整数。至少匹配n次。例如,"o{2,)"和"Bob”中的"o”不匹配,但和"foooood"中的所有o匹配。"o{1}”与"o+”等效。"o{0,}”和"o*”等效。
{n,m}m和n是非负整数。至少匹配n次而至多匹配 m次。例如,"o{1,3]"和"fooooood”中的前三个o匹配。"o{0,1}”和“o?”等效。
[xyz]匹配括号内的任一字符。例如,"[abc]"和"plain”中的"a”匹配。

[^xyz]匹配非括号内的任何字符。例如,"[^abc]"和“plain”中的"p”匹配。
[a-z]字符范围。和指定范围内的任一字符匹配。例如,"[a-z]”匹配"a"到"z"范围内的任一小写的字母表字符。

[^m-z]否定字符范围。匹配不在指定范围内的任何字符。例如,"[m-z]”匹配不在"m"到"z"范围内的任何字符。

前/后向查找:匹配括号中的内容(不包含括号)

前端开发中的ajax请求、axios封装

后向查找:(?<=exp)是以exp开头的字符串, 但不包含本身.

前向查找:(?=exp)就匹配为exp结尾的字符串, 但不包含本身.

负后向查找(?<!exp) ,在之前被指定的子表达式不能被匹配到

负前向查找::(?!exp),在之后被指定的子表达式不能被匹配到

正向先行断言 (?=\=) 表示在匹配等号 = 前面的位置进行断言,即正向这个位置后面必须跟着等号 = 才能进行匹配。这种断言不会消耗实际的字符。

前向查找 (?==) 表示匹配等号 =,并且把等号 = 包含在匹配结果中。这种查找会消耗等号 = 这个字符。

泛型(传参给类型)

function printValue<T>(value: T): void {
  console.log(value);
}

// 使用泛型参数传递参数类型
printValue<string>("Hello, World!"); // 输出: Hello, World!
printValue<number>(42); // 输出: 42
printValue<boolean>(true); // 输出: true

src/api/common.ts封装请求

import request from '@/utils/request'
const baseUrl = process.env.NODE_ENV === 'development' ? '/test' : ''
const mock = false

// 查看自己信息接口
export const commonQuery = (data: any) => {
  const url = mock ? `${baseUrl}/common/query` : `${baseUrl}/mock/query`
  return request.post(url, data)
}

// 查看自己信息接口
export const getUserInfo = () => {
  const url = `${baseUrl}/menu/userInfo`
  return request.get(url)
}

//具体使用那种 与后端设置相关
// request.post(url, data)与
// request({
//     url, 
//     method: 'post',
//     params: data
//   })
// }
// 都是返回promise对象

src/views/components二次封装请求

import * as API from "@/api/common"
import { debounce } from 'lodash'
...
// 业绩指标list
  baseIndexQuaryScoreIndex = debounce(this.baseIndexQuaryScoreIndexAPI, 100)
  async baseIndexQuaryScoreIndexAPI(type: string) {
    try {
      const res = await API.getQuery()
      if (res && res.code == 200) {
        this.quaryScoreIndexList = res.data || []
      } else {
        this.$message.error(res.msg || '接口错误')
      }
    } catch (e: any) {
      this.$message.error(e.msg || '接口错误')
    }
  }

//await API.getQuery()等价于API.getQuery().then

  baseIndexQuaryScoreIndex() {
    API.getQuery().then((res: any) => {
      if (res && res.code == 200) {
        this.quaryOtherIndexList = res.data || []
      } else {
        this.$message.error(res.msg || '接口错误')
      }
    }).catch((e: any) => {
      this.$message.error(e.msg || '接口错误')
    })
  }

//调用
this.baseIndexQuaryScoreIndex()

基础知识回顾

url参数

http://example.com/page?param1=value1&param2=value2#section1

分隔实际的URL和参数
& URL中指定的参数间的分隔符
= 左边为参数名、右边参数值
#

锚点(Anchor),用于标识文档中的特定位置或元素,

仅在客户端使用,并且由浏览器处理,不发送到服务器

指示浏览器滚动到具有 id="section1" 的元素处。

location属性值

window的全局对象,表示当前页面http://www.example.com/path/index.html

window.location.href:获取/设置 url

window.location.orgin:协议、主机名和端口号部分

//https://www.example.com:8080/page.html
//     ://               :
//https%3A%2F%2Fwww.example.com%3A8080。
encodeURIComponent(window.location.origin)
//encodeURIComponent用于将字符串中的特殊字符(空格、&、+、= 、?)转换为编码形式,确保URL中不包含任何无效字符



//查询参数时 或者 动态参数时 需要encodeURIComponent
const url = 'https://example.com/api?param=' + encodeURIComponent(queryParam);
window.location.href =`https://www.example.com/path/to/resource.html/domain=${location.host}&req=${encodeURIComponent(location.pathname)}&protocol=https${location.hash}`

window.location.protocol: 协议http

window.location.host:主机+端口(host:8080)/IP地址(127.123.32.1唯一)/域名(www.example.com助记)

window.location.hostname:主机host

window.location.port:端口8080

window.location.pathname: 资源路径path/index.html,资源index.html

window.location.hash:

window.location.search: 搜索

var searchParams = new URLSearchParams(window.location.search);
console.log(searchParams.get('name')); // 输出 "John"

同源策略

同源/域:顾名思义,域名包括前缀都要相同,自然也包括端口号

但是cookie从端口号开始就可以不同

跨域请求默认情况下不会携带 Cookie。

然而,可以通过设置 CORS(跨源资源共享)头部来允许携带 Cookie 进行跨域请求

token和cookie

凭证 token cookie
跨域

token 完全由应用管理,所以它可以避开同源策略

服务器端生成管理,不能跨域
与session

移动端对 cookie 的支持不是很好,所以移动端常用的是 token

session 需要基于 cookie 实现

替换cookie(开发中模拟不同权限的用户)

A.手动

前端开发中的ajax请求、axios封装

B.设置index.html 
<!DOCTYPE html>
<html lang="">
  <head>
...
    <div id="app"></div>
    <script>
      document.cookie = 'sso_ticket=xx'
    </script>
  </body>
</html>
C.浏览器扩展小程序:一键获取/设置多个

获取项目网页中的cookies,然后在本地的项目网页中设置

web安全


XSS跨站脚本攻击Cross-Site Scripting(登陆时执行脚本读取)

解决:文章来源地址https://www.toymoban.com/news/detail-510098.html

  • url参数使用encodeURIComponent方法转义
  • 尽量不用InnerHtml插入HTML内容

CSRF跨站请求伪造Cross-site request forgery(凭证请求)

解决:添加验证码、使用token

SQL注入攻击(交表单/输域名 执行SQL命令)

解决:表单输入时通过正则表达式将一些特殊字符进行转换

DDoS攻击分布式拒绝服务 Distributed Denial of Service(请求过载)

解决:

  • 限制单IP请求频率。
  • 检查特权端口的开放

到了这里,关于前端开发中的ajax请求、axios封装的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端vue2中axios封装请求数据,教会你封装教会你请求数据 简单易懂,轻松学会axios封装请求数据 看一眼就会 手把手教会

    2、完成上面的步骤还不够,还需要再创建一个文件夹api,然后在文件夹里面创建自定义的文件名(我创建的是cartApi.js)文件名根据自己的需求命名 下面就是根据自己的请求接口以及数据参数请求,下面的请求是一些常见的post、get请求以及传参啥的(仅供参考,可以参考下面

    2024年02月03日
    浏览(25)
  • 前端异步请求并解决跨域问题(Ajax+axios框架)、后端响应多个数据(JSON)

    目录 一、前后端同步异步请求 1.同步请求: 2.异步请求: 3.跨域问题(前端问题) 4.axios框架(封装后) 二、后端向前端响应多个数据-JSON 1.同步请求:         发送一个请求,回应请求,回应的内容会覆盖浏览器中的内容,这样会 打断 前端其他的正常操作。 2.异步请求:

    2024年02月07日
    浏览(52)
  • Java网络开发(Asynchronous异步)—— 从 Jsp 到 Ajax 的 axios 到 vue & 同步请求 到 异步请求

    如果想做bilibili那样的边看视频边评论怎么搞?; 之前用jsp的方式,是无法实现这个需求的,因为每次评论后提交了评论,会把整个页面全部刷新,导致视频也回到未播放的初始状态,如下所示: 代码为: 这是因为,在每次浏览器请求后,只能等待服务器的响应,即这种方

    2024年02月09日
    浏览(31)
  • 全栈笔记_浏览器扩展篇(插件开发 - 发送axios请求)

    是一个基于 promise 的HTTP库 兼容浏览器和node.js环境,在浏览器中会创建 XMLHttpRequests 请求,在node.js中会创建 http 请求 安装依赖: yarn add axios 创建实例: 使用自定义配置新建一个 axios 实例

    2024年02月19日
    浏览(31)
  • 关于前端开发中常用的 axios 封装

    前端、axios、网络请求 关于前端开发中常用的 axios 封装 jcLee95 的个人博客:https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343 邮箱 : 291148484@163.com 本文地址 :https://blog.csdn.net/qq_28550263/article/details/131099244 相关文章:[《flutter 中的 dio 模块用法解析与二次封装》](https://blog.csdn.net

    2024年02月08日
    浏览(30)
  • 前端(二十七)——封装指南:Axios接口、常用功能、Vue和React中的封装技术

    😊博主:小猫娃来啦 😊文章核心: 前端封装指南:Axios接口、常用功能、Vue和React中的封装技术 在我们前端开发当中,封装是种将代码和功能组织起来以便重复使用的方式。它可以使开发人员更高效地编写、维护和管理代码。本文将探讨前端封装的定义、重要性以及在Web开

    2024年02月05日
    浏览(28)
  • 二次封装ajax和axios

    2024年02月14日
    浏览(27)
  • 【Ajax】如何通过axios发起Ajax请求

    ✍️ 作者简介: 前端新手学习中。 💂 作者主页: 作者主页查看更多前端教学 🎓 专栏分享:css重难点教学   Node.js教学 从头开始学习   ajax学习 Axios是专注于网络数据请求的库,相比于原生的XMLHttpRequest对象,axios简单易用。相比于Jquery,axios更加轻量化,只专注于网络数据请

    2024年02月02日
    浏览(30)
  • 【AJAX】axios发送请求

    引入axios 以下是axios的GET请求格式: 以下是axios的POST请求格式: 注意:params中的键值对数据是拼接在url上,无论是post还是get请求。 axios

    2024年02月13日
    浏览(42)
  • 【Ajax】笔记-Axios与函数发送AJAX请求

    1、Axios是一个基于Promise的HTTP库,而Ajax是对原生XHR的封装; 2、Ajax技术实现了局部数据的刷新,而Axios实现了对ajax的封装。 ajax: 本身是针对MVC的编程,不符合现在前端MVVM的浪潮 基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案 JQuery整个项目太大,单纯使用

    2024年02月16日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包