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