封装--ajax

参数:

  1. 请求地址(url)

  2. 请求方式(method)

  3. 是否异步(async)

  4. 携带给后端的参数(data)

  5. 是否存在 token(token)

  6. 是否对响应体进行解析(dataType)

  7. 请求成功后执行的函数(success)

参数是否有默认值:

  1. url: 没有, 必填

  2. method: 可以有, GET

  3. async: 可以有, 默认 true, 选填是 false 表示非异步

  4. data: 可以有, ''

  5. token: 可以有, ''

  6. dataType: 可以有, 'string' 表示不执行 JSON.parse(), 选填 'json' 表示执行 JSON.parse()

  7. success: 可以有, 默认是一个空函数

对你传递的参数进行验证

1-1. 验证你的 options 内 url 必填

  => 如果你没有 url, 不需要继续执行代码了

1-2. 验证你的 options 内的 method 填写

  => 可以不传递, 只要你传递了, 必须是 GET 或者 POST

1-3. 验证你的 options 内的 async 填写

  => 可以不传递, 只要你传递了, 必须是 true 或者 false

1-4. 验证你的 options 内的 data 填写

  => 可以不传递, 只要你传递了, 必须是 字符串 类型

1-5. 验证你的 options 内的 token 填写

  => 可以不传递, 只要你传递了, 必须是 字符串 类型

1-6. 验证你的 options 内的 dataType 填写

  => 可以不传递, 只要你传递了, 必须是 'string' 或者 'json'

1-7. 验证你的 options 内的 success 填写

  => 可以不传递, 只要你传递了, 必须是一个 function 类型


function ajax(options = {}) {
  // options 就是你传递进来的所有对于本次请求的配置信息
  // console.log('你传递进来的数据 : ', options)

  // 1. 参数验证
  // 1-1. 验证 options.url
  if (!options.url) {
    // 表示 url 是 undefined 或者 null 或者 '' 或者 0
    // 手动抛出异常
    // 语法: throw new Error('报错信息')
    // 作用: 直接在控制台报错, 阻断程序的继续执行
    throw new Error('url 为必填选项, 请填写 ^_^')
  }

  // 1-2. 验证 options.method
  // 可以是 undefined, 可以是 'GET', 可以是 'POST'
  if (!(options.method === undefined || /^(get|post)$/i.test(options.method))) {
    // 代码能执行到这里, 说明你的 method 不是 undefined 不是 get 不是 post
    throw new Error('目前版本只接受 GET 和 POST 请求, 请期待更新 !! (#^.^#)')
  }

  // 1-3. 验证 options.async
  // 可以是 undefined, 可以是 布尔值
  if (!(options.async === undefined || typeof options.async === 'boolean')) {
    throw new Error('async 只能传递 布尔值, 请检查后操作')
  }

  // 1-4. 验证 options.data
  if (!(options.data === undefined || typeof options.data === 'string')) {
    throw new Error('data 需要传递一个 字符串 格式')
  }

  // 1-5. 验证 options.token
  if (!(options.token === undefined || typeof options.token === 'string')) {
    throw new Error('token 需要传递一个 字符串 格式')
  }

  // 1-6. 验证 options.dataType
  if (!(options.dataType === undefined || /^(string|json)$/i.test(options.dataType))) {
    throw new Error('dataType 只能传递 "string" 或者 "json"')
  }

  // 1-7. 验证 options.success
  if (!(options.success === undefined || typeof options.success === 'function')) {
    throw new Error('success 需要传递一个 function 类型的数据')
  }

  // 2. 设置一套默认值
  const _default = {
    // 代码能执行到这里, 说明 url 必须有值
    url: options.url,
    // 代码能来到这里, 说明 method 要么是 undefined, 要么是 GET, 要么是 POST
    method: options.method || 'GET',
    // 代码能来到这里, 说明 async 要么是 undefined, 要么是 true 要么是 false
    async: typeof options.async === 'boolean' ? options.async : true,
    // async: options.async ?? true
    // 代码能来到这里, 说明 data 要么是 undefined, 要么是 字符串
    data: options.data || '',
    // 代码能来到这里, 说明 token 要么是 undefined, 要么是 字符串
    token: options.token || '',
    // 代码能来到这里, 说明 dataType 要么是 undefined, 要么是 string 或者 json
    dataType: options.dataType || 'string',
    // 代码能来到这里, 说明 success 要么是 undefined, 要么是一个 函数
    success: options.success || function () {},
    error: options.error || function () {}
  }
  // 2-2. 判断一下, 如果是 GET 请求, 并且 data 有内容
  // 那么我们直接把 data 拼接到 url 的后面
  if (_default.method.toUpperCase() === 'GET' && _default.data) {
    // 代码能来到这里, 说明 是 GET 请求, 并且 data 有内容
    _default.url += '?' + _default.data
  }

  // 3. 按照 _default 内的内容发送请求

  // 3-1. 创建 ajax 对象
  const xhr = new XMLHttpRequest()

  // 3-2. 配置请求信息
  xhr.open(_default.method, _default.url, _default.async)

  // 3-3. 接受响应
  xhr.onload = function () {
    // 判断一下, 如果 dataType 是 'string' 那么我就不执行 JSON.parse()
    // 如果你的 dataType 是 'json' 那么我就执行一下 JSON.parse()
    const result = _default.dataType.toUpperCase() === 'JSON' ? JSON.parse(xhr.responseText) : xhr.responseText

    // 请求完成, 只要调用 success 函数就可以了
    _default.success(result)
  }

  // 3-4. 是否填写 token 作为请求头内的一个信息
  if (_default.token) xhr.setRequestHeader('authorization', _default.token)

  // 3-5. 如果是 POST 请求, 设置一下请求头的格式
  if (_default.method.toUpperCase() === 'POST') xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')

  // 3-6. 发送请求
  // 如果是 GET 请求, 直接书写 xhr.send()
  // 如果是 POST 请求你, 书写 xhr.send(参数)
  _default.method.toUpperCase() === 'POST' ? xhr.send(_default.data) : xhr.send()
}
  // 本页面需要获取个人信息
  // 刚好个人信息需要 token 验证
  // 请求一下 个人 信息
ajax({
  url: 'http://localhost:8888/users/info',
  data: `id=${ id }`,
  dataType: 'json',
  token: token,
  success: function (res) {
    // 判断登录状态是过期的
    if (res.code !== 1) {
      // 向 localStorage 内存储一个叫做 url 的键, 值对应的是 'rpwd' 字符串
      window.localStorage.setItem('url', 'rpwd')
      window.location.href = './login.html'
      return
    }
  }
})

二次封装

//在基础的一次ajax后接着写
// 对 ajax 进行 二次封装

function pAjax(options = {}) {
  const p = new Promise((resolve, reject) => {
    // 执行 ajax
    ajax({
      url: options.url,
      data: options.data,
      token: options.token,
      async: options.async,
      method: options.method,
      dataType: options.dataType,
      success: function (res) {
        resolve(res)
      }
    })
  })

  // 把我的 promise 对象返回出去
  return p
}

// 此时的全局变量 a 和 pAjax 内的 局部变量 p 是一模一样的东西
// const a = pAjax({ url: '/xxx', data: 'xxx', dataType: 'xxxx' })
// a.then(res => {})

/*
  需求:
    1. 发送请求到 /test/first
    2. 发送请求到 /test/second
      => 前提: 必须要等到第一个请求结束以后再次发送
    3. 发送请求到 /test/third
      => 前提: 必须要等到第二个请求结束以后再次发送
*/
// 使用我按照 promise 形式封装的 pAjax 函数来完成
pAjax({ url: 'http://localhost:8888/test/first' })
  .then(res => {
    console.log('第一个请求结束了')
    console.log(res)

    // return 一个新的 promise 对象
    return pAjax({
      url: 'http://localhost:8888/test/second',
      dataType: 'json'
    })
  })
  .then(res => {
    console.log('第二个请求结果')
    console.log(res)

    // return 一个新的 promise 对象
    return pAjax({
      url: 'http://localhost:8888/test/third',
      data: 'name=Jack&age=20',
      dataType: 'json'
    })
  })
  .then(res => {
    console.log('第三次请求的结果')
    console.log(res)
  })

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值