Promise封装ajax

Promise封装原生ajax

今日目标:

1.node的内置模块url, http

2.Promise封装原生ajax

00-回顾

javascript 复制代码
# express: node内置的一个用来搭建后台服务的框架

# 使用: 
全局安装: yarn global add express-generator | npm i express-generator -g

创建后台服务:express 项目名

启动项目:
	yarn | npm i: 找回第三方的模块
	yarn start | npm run start: 启动项目

01-node的内置模块

javascript 复制代码
# url: 操作网址
let url = require('url')
url.parse('网址', [布尔值: 决定是否将查询字符串转换为对象格式]): 将网址解析成对象

# http: 创建本地服务器
let http = require('http')

let server = http.createServer(function (req, res) {
    // req: 前端提交的数据
    // res: 后端响应的内容
    console.log('服务器被访问了一次');
})
server.listen('8888', console.log('服务器启动成功'))

02-Promise封装ajax【面试题】

javascript 复制代码
/* 
    参数:
        1. 请求地址,url: 必填
        2. 请求方式,method: 选填 默认get请求
        3. 提交的参数,data: 选填 默认值 ''
        4. post的请求头, headers:选填, 默认值 {content-type, 'application/x-www-form-urlencoded'}

    返回值:
        => 必须
        => 返回的内容可以是回调函数, 可能会造成回调地狱
        => 建议选择的是返回Promise,可以支持async/await

    函数封装的方法:相同部分放到函数体内,不同部分传参搞定

    函数封装的原则:尽可能的让程序的兼容性更强
        => 参数是否齐全
        => 参数的格式是否正确
    
*/

// 将对象转换为查询字符串
function queryStringify(data) {
    let str = ''
    for (let key in data) {
        str += `${key}=${data[key]}&`
    }
    return str.slice(0, -1)
}

function createAjax(url) {
    var BaseURL = url
    function ajax(options = {}) {
        // 这里options参数选择了对象:对象可以不用考虑参数的顺序
        // throw new Error(): 创建一个错误信息对象,并抛出(显示在控制台)
        // 1.1 请求地址是必填项
        if (!options.url) throw new Error('请求地址是必填项')
        // 1.2 请求方式 这个地方可以是undefined, 也可以是'GET'或'POST'
        if (!(options.method === undefined || /^(GET|POST)$/i.test(options.method))) {
            throw new Error('目前仅支持GET或POST,敬请期待更多方式')
        }
        // 1.3 提交的参数 这个地方也可以undefined,也可以是字符串,也可以是对象
        if (!(options.data === undefined || typeof options.data === 'string' || options.data.constructor === Object)) {
            throw new Error('支持的数据类型可以是字符串或者对象')
        }
        // 1.4 post请求头,可以是undefined, 也可以是表单格式提交
        if (/^POST$/i.test(options.method)) {
            if (!(options.headers === undefined || options.headers['content-type'] === 'application/x-www-form-urlencoded' || options.headers['content-type'] === 'application/json')) {
                throw new Error('post请求,必须设置请求头')
            }
        }


        // 如果options里面的参数不包含请求方式和提交参数,就要提供默认值
        let _default = {
            url: BaseURL + options.url,
            method: options.method || 'GET',
            data: options.data || '',
            headers: options.headers || { 'content-type': 'application/x-www-form-urlencoded' }
        }

        // 提交的参数的格式可以是对象形式,就需要将对象先转换成查询字符串,再做拼接
        if (_default.data.constructor === Object) _default.data = queryStringify(_default.data)

        // 注意:如果请求方式是get,并且需要携带参数,就需要把参数拼接在url地址的后面
        if (/^GET$/i.test(_default.method) && _default.data) _default.url += '?' + _default.data

        // 注意:发送了请求之后,希望可以接收到响应的数据,这里就使用了Promise, 再将结果resolve出去即可
        let p = new Promise((resolve, reject) => {
            // 2. 发起ajax请求
            // 2.1 创建一个实例对象,负责发起请求和接收响应的数据
            let xhr = new XMLHttpRequest()
            // 2.2 配置请求方式和请求地址
            xhr.open(_default.method, _default.url)
            // 2.3 设置请求头信息
            // xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
            if (/^POST$/i.test(_default.method)) xhr.setRequestHeader('content-type', _default.headers['content-type'])
            // // 2.4 发送请求
            xhr.send(/^POST$/i.test(_default.method) && _default.data)
            // 2.4 监听请求状态
            xhr.onreadystatechange = function () {
                // 如果请求的状态码等于4 并且 http请求码等于200
                if (xhr.readyState === 4 && xhr.status === 200) {
                    let res = JSON.parse(xhr.responseText)
                    // console.log(res);
                    resolve(res)
                }
            }
        })
        return p
    }
    return ajax
}

# 方法调用
 async function fun() {
     let ajax = createAjax('http://115.159.153.85:8001')
     let r1 = await ajax({
         url: '/getTest',
         // method: 'POST',
         // headers: { 'content-type': 'application/json' },
         data: {
             name: 'xdj',
             age: 18
         }
     })
     let r2 = await ajax({
         url: '/postTest',
         method: 'POST',
         // headers: { 'content-type': 'application/json' },
         data: {
             name: r1.msg.slice(0, 3),
             age: 18
         }
     })
  }
fun()
相关推荐
摸鱼仙人~7 分钟前
Redux Toolkit 快速入门指南:createSlice、configureStore、useSelector、useDispatch 全面解析
开发语言·javascript·ecmascript
小声读源码32 分钟前
【技巧】dify前端源代码修改第一弹-增加tab页
前端·pnpm·next.js·dify
假客套41 分钟前
2025 后端自学UNIAPP【项目实战:旅游项目】7、景点详情页面【完结】
前端·uni-app·旅游
程序员小张丶1 小时前
基于React Native开发HarmonyOS 5.0主题应用技术方案
javascript·react native·react.js·主题·harmonyos5.0
Captaincc1 小时前
Ilya 现身多大毕业演讲:AI 会完成我们能做的一切
前端·ai编程
teeeeeeemo1 小时前
Vue数据响应式原理解析
前端·javascript·vue.js·笔记·前端框架·vue
Sahas10191 小时前
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
前端·javascript·vue.js
Jinxiansen02111 小时前
Vue 3 实战:【加强版】公司通知推送(WebSocket + token 校验 + 心跳机制)
前端·javascript·vue.js·websocket·typescript
MrSkye1 小时前
React入门:组件化思想?数据驱动?
前端·react.js·面试
BillKu2 小时前
Java解析前端传来的Unix时间戳
java·前端·unix