将来使用的时候, 可能会遇到
回调地狱
效果不会有变化, 而且还能和
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不能为undefined
if (options.url === undefined) {
throw new Error('您没有传递url,url为必填')
}
// 请求方式: method => 默认值get
// 也就是说method可以是get、post和undefined
if (!(/^(get|post)$/i.test(options.method) || options.method === undefined)) {
throw new Error('method目前仅支持post或者get')
}
// 同步异步: async => 默认值true
// 也就是说 async可以为true,false和undefined
if (!(options.async === undefined || typeof (options.async) === 'boolean')) {
throw new Error('async目前仅支持true或false')
}
// 请求参数: data => 默认值 ''
// 参数data可以是字符串、对象和undefined
const 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/post
method: options.method || 'get',
// ??空值运算符 符号左边是undefined或者null,会运行符号右边的
async: options.async ?? true,
// 代码运行到这里,data可能是对象、字符串和undefined
data: 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,要么是JSON
if (_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 objToStr(obj) {
let str = "";
for (let k in obj) {
str += `${k}=${obj[k]}&`;
}
str = str.slice(0, str.length - 1);
return str;
}
function createAjax(url) {
let baseUrl = url;
function ajax(options) {
if (options.url === undefined) {
throw new Error("您没有传递 url, url 为 必传");
}
if (
!(
/^(GET|POST)$/i.test(options.method) ||
options.method === undefined
)
) {
throw new Error("method 目前仅支持 post 或者 get");
}
if (
!(options.async === undefined || typeof options.async === "boolean")
) {
throw new Error("async 目前仅支持 ture 或者 false");
}
const optionsDataType = Object.prototype.toString.call(options.data);
if (
!(
optionsDataType === "[object Object]" ||
optionsDataType === "[object String]" ||
optionsDataType === "[object Undefined]"
)
) {
throw new Error("data 目前仅支持 字符串或者 对象");
}
const headersType = Object.prototype.toString.call(options.headers);
if (
!(
headersType === "[object Undefined]" ||
headersType === "[object Object]"
)
) {
throw new Error("header 暂时仅支持 对象格式");
}
if (
!(
options.dataType === undefined ||
/^(string|json)$/.test(options.dataType)
)
) {
throw new Error("dataType 目前仅支持 'string' 或者 'json'");
}
const _options = {
url: baseUrl + options.url,
method: options.method || "GET",
async: options.async ?? true,
data: options.data || "",
headers: {
"content-type": "application/x-www-form-urlencoded",
...options.headers,
},
dataType: options.dataType || "string",
};
if (!(typeof _options.data === "string")) {
_options.data = objToStr(_options.data);
}
if (/^GET$/i.test(_options.method)) {
_options.url = _options.url + "?" + _options.data;
}
const p = new Promise(function (res, rej) {
const xhr = new XMLHttpRequest();
xhr.open(_options.method, _options.url, _options.async);
xhr.onload = function () {
try {
if (_options.dataType === "string") {
res({
code: 1,
info: xhr.responseText,
});
} else {
res({
code: 1,
info: JSON.parse(xhr.responseText),
});
}
} catch (error) {
res({
code: 0,
info: xhr.responseText,
});
}
};
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$/i.test(_options.method)
? xhr.send(_options.data)
: xhr.send();
});
return p;
}
return ajax;
}
const ajax = createAjax(confg.baseUrl);