【学习笔记77】ajax的函数封装

news2024/9/20 0:49:59

一、封装分析

(一 )封装方案

1、回调函数方式

将来使用的时候, 可能会遇到回调地狱

2、promise方式

效果不会有变化, 而且还能和 async/await 一起使用

(二)函数的参数

  1. 请求方式: method => 默认值 get
  2. 请求地址: url => 必填
  3. 同步异步: async => 默认值 true
  4. 请求参数: data => 默认值 ‘’
  5. 请求头: headers => 默认值 {content-type: application/x-www-form-urlencoded}
  6. 解析参数: dataType => 默认值 ‘string’

注意:将以上参数封装成对象(options)的形式更加方便

(三)函数的返回值

  • promise实例化对象
  • 让开发自己使用 .then或者 .catch

二、参数的验证

function ajax(options) {
    // 请求地址: url => 必填,也就是说url不能为undefined
    if (options.url === undefined) {
        throw new Error('您没有传递url,url为必填')
    }

    // 请求方式: method => 默认值get
    // 也就是说method可以是get、post和undefined
    if (!(/^(get|post)$/i.test(options.method) || options.method === undefined)) {
        throw new Error('method目前仅支持post或者get')
    }

    // 同步异步: async => 默认值true
    // 也就是说 async可以为true,false和undefined
    if (!(options.async === undefined || typeof (options.async) === 'boolean')) {
        throw new Error('async目前仅支持true或false')
    }

    // 请求参数: data => 默认值 ''
    // 参数data可以是字符串、对象和undefined
    const optionsDataType = Object.prototype.toString.call('options.data');
    if (!(
        optionsDataType === "[object Object]" ||
        optionsDataType === "[object String]" ||
        optionsDataType === "[object Undefined]"
    )) throw new Error('data目前仅支持字符或对象')

    // 请求头: headers => 默认值 {content-type: application/x-www-form-urlencoded}
    // headers可以时候undefined,也可以是对象
    const headersType = Object.prototype.toString.call(options.headers)
    if(!(headersType === '[object Undefined]' || headersType === '[object Object]')){
        throw new Error('headers暂时仅支持对象格式')
    }
    
    // 解析参数: dataType => 默认值 'string'
    // dataType参数可以是undefined、'string'和'json'
    if(options.dataType === undefined || /^(string|json)$/.test(options.dataType)){
        throw new Error('dataType目前净资产string和JSON')
    }
    console.log(options);
}

ajax({
    url: 'http://localhost:8888',
    data: 'key=value',
    method: 'get',
    async: true,
    headers: {
        'content-type': 'application/x-www-form-urlencoded'
    },
    dataType: ''
})

在这里插入图片描述

验证:当我们不传url时

ajax({
    data: 'key=value',
    method: 'get',
    async: true,
    headers: {
        'content-type': 'application/x-www-form-urlencoded'
    },
    dataType: ''
})

在这里插入图片描述

三、处理默认参数

1、补充知识点

  • ??:空值运算符
  • 作用:符号左边是undefined或者null,会运行符号右边

2、封装函数处理data对象

function objToStr(obj){
    let str = '';
    for(let key in obj){
        str += `${key}=${obj[key]}&`;
    }
    str = str.slice(0, str.length-1);
    return str;
}

3、结构解析

	let obj1 = {
	    a: 1,
	    b: 2
	}
	
	let obj2 ={
	    c: 3,
	    d: 4,
	    ...obj1
}
console.log(obj2);

在这里插入图片描述

4、处理默认参数

  • 继续在ajax函数里面书写
    // 默认传输的处理
    const _options = {
        // 代码执行到这个位置 说明url一定传递了
        url: options.url,

        // 代码运行到这里,method要么是undefined,要么是get/post
        method: options.method || 'get',
        // ??空值运算符 符号左边是undefined或者null,会运行符号右边的
        async: options.async ?? true,

        // 代码运行到这里,data可能是对象、字符串和undefined
        data: options.data || '',

        // 代码运行这里 headers可能是undefined或对象
        headers: {
            "content-type": "application/x-www-form-urlencoded",
            ...options.headers,
        },

        // 代码运行到这里 dataType可能是undefined或者字符串
        dataType: options.dataType || 'string',
    }

    // 处理_options.data中对象转化为模板字符串
    if (!(typeof (_options.data) === 'string')) {
        // console.log(_options.data);
        _options.data = objToStr(_options.data)
    }

    console.log('原始对象', options);
    console.log('默认数据', _options);

在这里插入图片描述

四、设置get和post请求头

  • GET请求:不需要content-type,可能需要authorization
  • POST请求:需要content-type,可能需要authorization
    // 如果当前是get请求 在路径后拼接参数
    if (/^grt$/i.test(_options.method)) {
        _options.url = options.url + '?' + _options.data
    }

    // 发送请求
    const p = new Promise((res, rej) => {
        const xhr = new XMLHttpRequest();
        xhr.open(_options.method, _options.url, _options.async);
        xhr.onload = function () {
            // 代码运行到这里 dataType要么是string,要么是JSON
            if (_options.dataType === 'string') {
                res(xhr.responseText);
            } else {
                res(JSON.parse(xhr.responseText))
            }
        };

        // 对post请求认证的处理
        if (/^post$/i.test(_options.method)) {
            xhr.setRequestHeader('content-type', _options.headers["content-type"])
        }

        if (_options.headers.authorization) {
            xhr.setRequestHeader('authorization', _options.headers.authorization)
        }

        // 如果当前是post请求,那么send内部需要添加参数 否则不需要
        /^POST$/i.test(_options.method) ? xhr.send(_options.data) : xhr.send();
    })
    return p;

五、完整代码

function createAjax(url){
    let baseUrl = url;
    function ajax(options) {
        // 请求地址: url => 必填,也就是说url不能为undefined
        if (options.url === undefined) {
            throw new Error('您没有传递url,url为必填')
        }
    
        // 请求方式: method => 默认值get
        // 也就是说method可以是get、post和undefined
        if (!(/^(get|post)$/i.test(options.method) || options.method === undefined)) {
            throw new Error('method目前仅支持post或者get')
        }
    
        // 同步异步: async => 默认值true
        // 也就是说 async可以为true,false和undefined
        if (!(options.async === undefined || typeof (options.async) === 'boolean')) {
            throw new Error('async目前仅支持true或false')
        }
    
        // 请求参数: data => 默认值 ''
        // 参数data可以是字符串、对象和undefined
        const optionsDataType = Object.prototype.toString.call('options.data');
        if (!(
            optionsDataType === "[object Object]" ||
            optionsDataType === "[object String]" ||
            optionsDataType === "[object Undefined]"
        )) throw new Error('data目前仅支持字符或对象')
    
        // 请求头: headers => 默认值 {content-type: application/x-www-form-urlencoded}
        // headers可以时候undefined,也可以是对象
        const headersType = Object.prototype.toString.call(options.headers)
        if (!(headersType === '[object Undefined]' || headersType === '[object Object]')) {
            throw new Error('headers暂时仅支持对象格式')
        }
    
        // 解析参数: dataType => 默认值 'string'
        // dataType参数可以是undefined、'string'和'json'
        if (!(options.dataType === undefined || /^(string|json)$/.test(options.dataType))) {
            throw new Error('dataType目前仅支持string和JSON')
        }
    
        // 默认传输的处理
        const _options = {
            // 代码执行到这个位置 说明url一定传递了
            url: baseUrl + options.url,
    
            // 代码运行到这里,method要么是undefined,要么是get/post
            method: options.method || 'get',
            // ??空值运算符 符号左边是undefined或者null,会运行符号右边的
            async: options.async ?? true,
    
            // 代码运行到这里,data可能是对象、字符串和undefined
            data: options.data || '',
    
            // 代码运行这里 headers可能是undefined或对象
            headers: {
                "content-type": "application/x-www-form-urlencoded",
                ...options.headers,
            },
    
            // 代码运行到这里 dataType可能是undefined或者字符串
            dataType: options.dataType || 'string',
        }
    
        // 处理_options.data中对象转化为模板字符串
        if (!(typeof (_options.data) === 'string')) {
            // console.log(_options.data);
            _options.data = objToStr(_options.data)
        }
    
        // 如果当前是get请求 在路径后拼接参数
        if (/^grt$/i.test(_options.method)) {
            _options.url = options.url + '?' + _options.data
        }
    
        // 发送请求
        const p = new Promise((res, rej) => {
            const xhr = new XMLHttpRequest();
            xhr.open(_options.method, _options.url, _options.async);
            xhr.onload = function () {
                // 代码运行到这里 dataType要么是string,要么是JSON
                if (_options.dataType === 'string') {
                    res(xhr.responseText);
                } else {
                    res(JSON.parse(xhr.responseText))
                }
            };
    
            // 对post请求认证的处理
            if (/^post$/i.test(_options.method)) {
                xhr.setRequestHeader('content-type', _options.headers["content-type"])
            }
    
            if (_options.headers.authorization) {
                xhr.setRequestHeader('authorization', _options.headers.authorization)
            }
    
            // 如果当前是post请求,那么send内部需要添加参数 否则不需要
            /^post$/i.test(_options.method) ? xhr.send(_options.data) : xhr.send();
        })
        return p;
    }
    
    return ajax;
}

function objToStr(obj) {
    let str = '';
    for (let key in obj) {
        str += `${key}=${obj[key]}&`;
    }
    str = str.slice(0, str.length - 1);
    return str;
}

// 基址:闭包实现
const ajax = createAjax("http://localhost:8888");
const ajax1 = createAjax("http://localhost:8080");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/58609.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android开发——Jetpack Compose的使用

Android开发——Jetpack Compose的使用什么是Jetpack ComposeJetpack Compose带来的变化Jetpack Compose的两种运用方法将Jetpack Compose 添加到现有项目1.gradle 配置2.使用Kotlin-Gradle 插件3. 添加依赖项创建一个新的支持Jetpack Compose的项目1.创建一些简单应用定义可组…

12.3做题

一.车队问题 1.思路: 先把所在位置进行排序,升序排序, 计算出每辆车在不受其余车的影响时,行驶到终点需要的时间 从后往前看 对于相邻的两辆车 S 和 F,F 的起始位置大于 S,如果 S 行驶到终点需要的时间小于等于 F,那么 S 一定…

MySQL集群搭建-MMM高可用架构

MySQL集群搭建-MMM高可用架构 原文地址 https://segmentfault.com/a/1190000017286307 1 MMM 介绍 1.1 简介 MMM 是一套支持双主故障切换以及双主日常管理的第三方软件。MMM 由 Perl 开发,用来管理和监控双主复制,虽然是双主架构&#xff…

volatile

是java虚拟机提供的轻量级的同步机制(乞丐版的synchronized) 具备三个性质:保证可见性,不保证原子性,禁止指令重排 前置知识: …

JS读取本地CSV文件数据

JS读取本地CSV文件数据 文件中的部分数据如图 需求是需要提取出文件的数据 使用到的模块是 Papa Parse 1. 依赖安装 yarn add papaparse papaparse的基本使用可以参考官方demo 2. 解析本地文件 首先需要注意, papaparse解析本地文件, 需要的文件格式是从DOM中获得的File…

GO高级特性 之 并发模型

本文介绍一些并发的基础知识、常见的并发模型一级Go语言的MPG并发模型及其运行原理 并发与并行的区别 -并发并行概念并发指同一时间段,多条命令在CPU上同时执行。并行指同一时刻,多条命令在CPU上执行运行原理并发程序不要求计算机有多核计算能力&#…

毕设选题推荐基于python的django框架医疗急诊预约系统

💖🔥作者主页:计算机毕设老哥🔥 💖 精彩专栏推荐订阅:在 下方专栏👇🏻👇🏻👇🏻👇🏻 Java实战项目专栏 Python实…

项目成本管理质量管理

项目成本管理-控制成本目录概述需求:设计思路实现思路分析1.EVM2.偏差指标3.Question:4.绩效指标5.典型偏差TCPIS曲线图绩效审查参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip …

[近两万字] MySQL大全

目录 单元1 创建数据库 1.1 创建数据库 1.查看数据库 2.选择数据库 3.删除数据库 1.2 创建数据表 1.查看表结构 2.查看所有数据表 3.复制表结构 4.删除表 5.修改表数据 5.1 修改表名 5.2 添加字段 5.3删除字段 5.4修改字段的数据类型 5.5修改字段的名称 5.6修改字段…

[网络工程师]-应用层协议-SNMP

简单网络管理协议(Simple Network Management Protocol,SNMP)是在应用层上进行网络设备间通信的管理协议,可以用于网络状态监视、网络参数设定、网络流量统计与分析、发现网络故障等。SNMP基于UDP协议,由SNMP协议、管理…

【交通建模】基于模型的自主交通仿真框架附matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法 …

【深入浅出Java并发编程指南】「难点 - 核心 - 遗漏」让我们一起探索一下CyclicBarrier的技术原理和源码分析

CyclicBarrier和CountDownLatch CyclicBarrier和CountDownLatch 都位于java.util.concurrent这个包下,其工作原理的核心要点: CyclicBarrier工作原理分析 那么接下来给大家分享分析一下JDK1.8的CyclicBarrier的工作原理。 简单认识CyclicBarrier 何为…

Nginx动静分离、缓存配置、性能调优、集群配置

一. Nginx动静分离 1. 准备 1个web程序:部署在7061端口,启动 【dotnet NginxWeb.dll --urls"http://*:7061" --ip"127.0.0.1" --port7061】 Nginx程序:监听7000端口 2. 目的 比如单独启动部署在7061端口下的web程序&am…

c++ 静态库,动态库的制作和使用

文章目录1.什么是库?2.静态库的制作1.静态库的命名规则2.静态库的制作与使用1.静态库的制作2.静态库的使用3.动态库的制作1.动态库的命名规则2.动态库的制作与使用1.动态库的制作2.动态库的使用3.动态库加载失败的原因4.静态库和动态库的对比1.程序编译成可执行文件…

[附源码]Python计算机毕业设计Django基于Java的失物招领平台

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

时序数据库选型

目录一、当前主流的时序数据库二、各库特性1、Influxdb2、Timescale3、Druid4、Kdb5、Graphite6、RRDtool7、OpenTSDB8、TDengine9、DolphinDB三、优缺点对比因为个人用的go,所以调研及对比主要针对适配了go语言的数据库。 一、当前主流的时序数据库 排名参考于h…

基于PHP+MySQL动漫专题网站系统的设计与实现

随着时代的发展,人们兴趣爱好也越来越广泛,动漫是当前年轻人比较钟爱的一个兴趣爱好之一,每年都会有大量的动漫爱好者定期的举办一些交流活动等,但是线下的这种交流方式明显不能满足当前动漫爱好者的需求,为此我开发了…

Zen of Python(python之禅)

在python中导入import this就会显式: 以下是中文英文翻译: Beautiful is better than ugly. 优美比丑陋好 Explicit is better than implicit. 清晰比晦涩好 Simple is better than complex. 简单比复杂好 Complex is better than complicated. 复杂比错…

【全干工程师必学】一文搞懂Vue2.0

一文搞懂Vue2.0一、前端工程化二、WebPack是什么基本使用实现奇偶行变色1.初始化包管理工具2.安装jquery3.在项目中安装webpack4.在项目中配置webpack5.运行代码mode 的可选值developmentproductionwebpack.config.js 文件的作用webpack 中的默认约定自定义打包的入口与出口web…

uni-app开发常用操作速查记录

记录一下uni-app中常用的使用方法或是操作步骤,方便后期速查使用. 1.设置对象属性 2.组件中数据变化监听方法 3.微信开发者工具中全局搜索与局部搜索 4.Page对象与Componet对象组成 5.tabbar页面切换方法 6.组件中自定义函数的参数传递 7.m…