写点什么

封装 Ajax

作者:Jason199
  • 2022 年 7 月 03 日
  • 本文字数:3761 字

    阅读完需:约 12 分钟

封装Ajax

封装 ajax 操作

        哪些作为参数使用

          请求方式

            type: 默认值 GET

          请求地址

        url: 必填

        是否异步

            async: 默认值 true

          是否执行 JSON.parse()

            dataType: 默认是 'string' 表示不解析, 'json'

          传递给后端的数据

            data: 'a=100&b=200' || { a: 100, b: 200 }

  确定一下传递参数的方式

          function ajax() {}

          ajax('./xxx.php', null, null, 'json', 'a=100')

          ajax({ type: 'GET' })

          对象的方式传递参数

  开始封装

        1. 参数验证: 你传递的是不是符合规则

          1-1. url 验证, 必填

//公共代码部分ajax({      url: './server/get.php',      data: { a:100, b:200 },      dataType: 'json',      success: function (xhr) {        console.log('请求成功');        console.log('我想渲染页面, 根据结果判断登录是否成功');        console.log(xhr);      },      error: function (err) {        console.log('请求失败');        console.log(err);      }    })function ajax(options = {}) {if (!options.url) {        throw new Error('url 为必填选项')      }}
复制代码

          1-2. type 验证, 可以不传递, 可以是 GET, 可以是 POST, 大小写无所谓,其他的都不行

function ajax(options = {}) {// 1-2. 验证 type      if (!(options.type == undefined || options.type.toUpperCase() === 'GET' || options.type.toUpperCase() === 'POST')) {        throw new Error('目前只接收 GET 或者 POST 请求方式, 请期待更新')      }}
复制代码

          1-3. async 验证, 可以不传递, 可以是 true 可以是 false

            可以不传递, 传递就是 boolean 类型

function ajax(options = {}) { // 1-3. 验证 async      if (!(options.async == undefined || typeof options.async === 'boolean')) {        throw new Error('async 需要一个 Boolean 数据类型')      }}
复制代码

          1-4. dataType 验证, 可以不传递, 要吗式 'string' 要吗式 'json'

function ajax(options = {}) {  // 1-4. 验证 dataType      if (!(options.dataType == undefined || options.dataType === 'string' || options.dataType === 'json')) {        throw new Error('目前只支持 string 和 json 格式解析, 请期待更新')      }}
复制代码

          1-5. data 验证, 可以不传递, 可以是字符串类型, 可以是 object 类型

function ajax(options = {}) {   // 1-5. 验证 data      if (!(options.data == undefined || typeof options.data === 'string' || Object.prototype.toString.call(options.data) === '[object Object]')) {        throw new Error('data 参数只支持 string 和 object 数据类型')      }}
复制代码

          1-6. success 和  error 验证, 可以不传递, 要吗就得式函数

function ajax(options = {}) {  // 1-6. 验证 success 和 error      if (!(options.success == undefined || typeof options.success === 'function')) {        throw new Error('success 传递一个函数类型')      }
if (!(options.error == undefined || typeof options.error === 'function')) { throw new Error('error 传递一个函数类型') }}
复制代码

设置一套默认值

 var _default = {        url: options.url,        // 代码能来到这里, 说名 undefined  get  post        type: options.type || 'GET',        // 代码能来到这里, 说明 undefined true false        // 三元表达式, 如果你式个 布尔值, 那么就用你的, 否则用 true        async: typeof options.async === 'boolean' ? options.async : true,        // 代码能来到这里, 说明 undefined 'string' 'json'        dataType: options.dataType || 'string',        // 代码能来到这里, 说明 undefined '' {}        data: options.data || '',        // 如果你传递了是一个 function, 就用你传递的, 否则我就给一个默认函数        success: options.success || function () {},        error: options.error || function () {}      }
// 到这里, _default.success 和 error 肯定式一个函数
// 2-2. 单独调整一下 data // 能来到这里, _default.data 只能是 '' {} if (typeof _default.data === 'object') { // 准备一个空字符串 var str = '' for (var key in _default.data) { str += key + '=' + _default.data[key] + '&' } // 拼接完毕以后, 把最后一位去掉, 从新赋值给 _default.data _default.data = str.slice(0, -1) }
复制代码

发送请求

var xhr = creXhr()
// 3-1. 请求地址, 如果是 get 请求 url + '?' + data // 如果式 post 请求 url // 判断, 如果是 get 请求, 那么我把 _default.url 修改一下 if (_default.type.toUpperCase() === 'GET' && _default.data) { _default.url += '?' + _default.data } xhr.open(_default.type, _default.url, _default.async) xhr.onreadystatechange = function () { if (xhr.status >= 200 && xhr.status < 300 && xhr.readyState === 4) { // 3-3. 判断 dataType 如果式 json 要解析 if (_default.dataType === 'json') { // 成功, 不需要打印 // 调用 _default.success() var res = JSON.parse(xhr.responseText) // 要吗调用的式你传递进来的函数, 要吗调用的式默认函数 // 调用的如果式默认函数, 那么就相当于什么都没执行 // 如果调用的式你传递进来的函数, 那么你在函数里面写什么就执行什么 _default.success(res) } else if (_default.dataType === 'string') { _default.success(xhr.responseText) } }
if (xhr.readyState === 4 && xhr.status >= 400) { _default.error(xhr.status) } }
// 3-2. 判断是不是 post 请求 if (_default.type.toUpperCase() === 'POST') { xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded') } xhr.send(_default.data) }
复制代码

封装 ajax

设计模式: 为了解决特定问题而给出的简洁优化的解决方案

        懒惰模式: 多种方案选择一种的方式

          四种方式

          封装的时候要判断

          假设: 刚好是第四个可以用

          再找个页面你创建两次的时候,

            第一次要判断到第四个

            第二次还是要判断到第四个

        懒惰模式, 第一次的时候, 判断到第四个, 从第二次开始, 不再进行判断


1. 封装创建 xhr 对象

封装一个函数, 创建 xhr 对象

        不需要参数

        返回值就是一个可以再本浏览器使用的 xhr 对象

每一种创建方式写成一个函数

          依次去调用找个函数

          如果不报错, 表示这个方法可以使用

          如果 a 函数可以使用, 表示 a 函数里面的代码再当前浏览器可以正常创建

          我把 creXhr 重新赋值, 赋值为 a

          从此以后, 当你再次调用 creXhr 的时候, 其实就是再调用 a 函数


四个函数放在一个数组里面

          循环遍历这个数组

          循环的尝试

准备一个开关

          判断数组里面是不是有能执行的

          开始的时候式 false

          一旦有一个可以使用 变量赋值为 true


function creXhr() { var xhr = null// 准备一个变量 var flag = false
// 根据各种判断, 来给 xhr 赋值 var arr = [ function a() { return new XMLHttpRequest() }, function b() { return new ActiveXObject('Microsoft.XMLHTTP') }, function c() { return new ActiveXObject('Msxml.XMLHTTP') }, function d() { return new ActiveXObject('Msxml2.XMLHTTP') } ]
for (let i = 0; i < arr.length; i++) {// arr[i] 式里面的每一个函数 try { xhr = arr[i]()// 这里的代码可以执行, 表示 arr[i] 函数里面写的代码就是当前浏览器用的 creXhr = arr[i] flag = true break } catch (e) {} }
// 判断 flag // 如果式 false, 表示数组里面的每一个都不能用 if (!flag) { xhr = '您的浏览器不支持 ajax, 请更换浏览器重试' throw new Error(xhr) } // 返回 xhr return xhr; }
复制代码


发布于: 刚刚阅读数: 3
用户头像

Jason199

关注

还未添加个人签名 2022.04.29 加入

一条努力上岸的咸鱼

评论

发布
暂无评论
封装Ajax_ajax_Jason199_InfoQ写作社区