封装 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; }
复制代码
评论