将来使用的时候, 可能会遇到
回调地狱
效果不会有变化, 而且还能和
async/await
一起使用
- 请求方式:
method
=> 默认值 get- 请求地址:
url
=> 必填- 同步异步:
async
=> 默认值 true- 请求参数:
data
=> 默认值 ‘’- 请求头:
headers
=> 默认值 {content-type: application/x-www-form-urlencoded}- 解析参数:
dataType
=> 默认值 ‘string’
注意:将以上参数封装成对象(options)
的形式更加方便
- promise
实例化对象
- 让开发自己使用
.then或者 .catch
function ajax(options) {// 请求地址: url => 必填,也就是说url不能为undefinedif (options.url === undefined) {throw new Error('您没有传递url,url为必填')}// 请求方式: method => 默认值get// 也就是说method可以是get、post和undefinedif (!(/^(get|post)$/i.test(options.method) || options.method === undefined)) {throw new Error('method目前仅支持post或者get')}// 同步异步: async => 默认值true// 也就是说 async可以为true,false和undefinedif (!(options.async === undefined || typeof (options.async) === 'boolean')) {throw new Error('async目前仅支持true或false')}// 请求参数: data => 默认值 ''// 参数data可以是字符串、对象和undefinedconst optionsDataType = Object.prototype.toString.call('options.data');if (!(optionsDataType === "[object Object]" ||optionsDataType === "[object String]" ||optionsDataType === "[object Undefined]")) throw new Error('data目前仅支持字符或对象')// 请求头: headers => 默认值 {content-type: application/x-www-form-urlencoded}// headers可以时候undefined,也可以是对象const headersType = Object.prototype.toString.call(options.headers)if(!(headersType === '[object Undefined]' || headersType === '[object Object]')){throw new Error('headers暂时仅支持对象格式')}// 解析参数: dataType => 默认值 'string'// dataType参数可以是undefined、'string'和'json'if(options.dataType === undefined || /^(string|json)$/.test(options.dataType)){throw new Error('dataType目前净资产string和JSON')}console.log(options);
}ajax({url: 'http://localhost:8888',data: 'key=value',method: 'get',async: true,headers: {'content-type': 'application/x-www-form-urlencoded'},dataType: ''
})
验证:当我们不传url时
ajax({data: 'key=value',method: 'get',async: true,headers: {'content-type': 'application/x-www-form-urlencoded'},dataType: ''
})
- ??:
空值运算符
- 作用:符号左边是
undefined或者null
,会运行符号右边
的
function objToStr(obj){let str = '';for(let key in obj){str += `${key}=${obj[key]}&`;}str = str.slice(0, str.length-1);return str;
}
let obj1 = {a: 1,b: 2}let obj2 ={c: 3,d: 4,...obj1
}
console.log(obj2);
继续在ajax函数里面书写
// 默认传输的处理const _options = {// 代码执行到这个位置 说明url一定传递了url: options.url,// 代码运行到这里,method要么是undefined,要么是get/postmethod: options.method || 'get',// ??空值运算符 符号左边是undefined或者null,会运行符号右边的async: options.async ?? true,// 代码运行到这里,data可能是对象、字符串和undefineddata: options.data || '',// 代码运行这里 headers可能是undefined或对象headers: {"content-type": "application/x-www-form-urlencoded",...options.headers,},// 代码运行到这里 dataType可能是undefined或者字符串dataType: options.dataType || 'string',}// 处理_options.data中对象转化为模板字符串if (!(typeof (_options.data) === 'string')) {// console.log(_options.data);_options.data = objToStr(_options.data)}console.log('原始对象', options);console.log('默认数据', _options);
GET请求
:不需要content-type,可能需要authorizationPOST请求
:需要content-type,可能需要authorization
// 如果当前是get请求 在路径后拼接参数if (/^grt$/i.test(_options.method)) {_options.url = options.url + '?' + _options.data}// 发送请求const p = new Promise((res, rej) => {const xhr = new XMLHttpRequest();xhr.open(_options.method, _options.url, _options.async);xhr.onload = function () {// 代码运行到这里 dataType要么是string,要么是JSONif (_options.dataType === 'string') {res(xhr.responseText);} else {res(JSON.parse(xhr.responseText))}};// 对post请求认证的处理if (/^post$/i.test(_options.method)) {xhr.setRequestHeader('content-type', _options.headers["content-type"])}if (_options.headers.authorization) {xhr.setRequestHeader('authorization', _options.headers.authorization)}// 如果当前是post请求,那么send内部需要添加参数 否则不需要/^POST$/i.test(_options.method) ? xhr.send(_options.data) : xhr.send();})return p;
function createAjax(url){let baseUrl = url;function ajax(options) {// 请求地址: url => 必填,也就是说url不能为undefinedif (options.url === undefined) {throw new Error('您没有传递url,url为必填')}// 请求方式: method => 默认值get// 也就是说method可以是get、post和undefinedif (!(/^(get|post)$/i.test(options.method) || options.method === undefined)) {throw new Error('method目前仅支持post或者get')}// 同步异步: async => 默认值true// 也就是说 async可以为true,false和undefinedif (!(options.async === undefined || typeof (options.async) === 'boolean')) {throw new Error('async目前仅支持true或false')}// 请求参数: data => 默认值 ''// 参数data可以是字符串、对象和undefinedconst optionsDataType = Object.prototype.toString.call('options.data');if (!(optionsDataType === "[object Object]" ||optionsDataType === "[object String]" ||optionsDataType === "[object Undefined]")) throw new Error('data目前仅支持字符或对象')// 请求头: headers => 默认值 {content-type: application/x-www-form-urlencoded}// headers可以时候undefined,也可以是对象const headersType = Object.prototype.toString.call(options.headers)if (!(headersType === '[object Undefined]' || headersType === '[object Object]')) {throw new Error('headers暂时仅支持对象格式')}// 解析参数: dataType => 默认值 'string'// dataType参数可以是undefined、'string'和'json'if (!(options.dataType === undefined || /^(string|json)$/.test(options.dataType))) {throw new Error('dataType目前仅支持string和JSON')}// 默认传输的处理const _options = {// 代码执行到这个位置 说明url一定传递了url: baseUrl + options.url,// 代码运行到这里,method要么是undefined,要么是get/postmethod: options.method || 'get',// ??空值运算符 符号左边是undefined或者null,会运行符号右边的async: options.async ?? true,// 代码运行到这里,data可能是对象、字符串和undefineddata: options.data || '',// 代码运行这里 headers可能是undefined或对象headers: {"content-type": "application/x-www-form-urlencoded",...options.headers,},// 代码运行到这里 dataType可能是undefined或者字符串dataType: options.dataType || 'string',}// 处理_options.data中对象转化为模板字符串if (!(typeof (_options.data) === 'string')) {// console.log(_options.data);_options.data = objToStr(_options.data)}// 如果当前是get请求 在路径后拼接参数if (/^grt$/i.test(_options.method)) {_options.url = options.url + '?' + _options.data}// 发送请求const p = new Promise((res, rej) => {const xhr = new XMLHttpRequest();xhr.open(_options.method, _options.url, _options.async);xhr.onload = function () {// 代码运行到这里 dataType要么是string,要么是JSONif (_options.dataType === 'string') {res(xhr.responseText);} else {res(JSON.parse(xhr.responseText))}};// 对post请求认证的处理if (/^post$/i.test(_options.method)) {xhr.setRequestHeader('content-type', _options.headers["content-type"])}if (_options.headers.authorization) {xhr.setRequestHeader('authorization', _options.headers.authorization)}// 如果当前是post请求,那么send内部需要添加参数 否则不需要/^post$/i.test(_options.method) ? xhr.send(_options.data) : xhr.send();})return p;}return ajax;
}function objToStr(obj) {let str = '';for (let key in obj) {str += `${key}=${obj[key]}&`;}str = str.slice(0, str.length - 1);return str;
}// 基址:闭包实现
const ajax = createAjax("http://localhost:8888");
const ajax1 = createAjax("http://localhost:8080");