1.封装AJAX工具函数
为了提升我们的开发效率,让用户在使用异步对象的时候通过调用一个相同的函数就可以实现需求,需要将XMLHttpRequest封装成一个函数。
封装异步操作,兼容get和post请求方式
1. 封装的整体流程
封装函数的关键在于做判断:
-
找到操作的共同点–直接拷贝
-
找到不同的部分–以后就是参数
-
请求方式:type
-
请求url:url
-
请求参数不一样:data
-
请求数据类型–返回数据的格式:dataType
-
请求成功之后的数据处理函数:success:是一个回调函数
-
函数的封装形式:为了解决全局污染,将封装函数定义到对象中
var $ = { ajax:function(option){ // 实现具体的业务处理 } }
function ajax (type, url, data, success) { // 这种函数定义的缺点 // 1.这种函数是全局定义,会造成全局污染(存放在内存中不释放,会造成内存溢出),用function定义的函数就是全局函数 // 2.参数顺序固定,用户不方便调用 // 3.参数的数量固定,不方便后期的扩展 } //将参数定义为一个对象 function ajax (option) { // 还是会造成全局污染 }
-
初步封装函数:
缺点:当用户传入数据类型为json和xml,返回数据格式出错。只能传入字符串类型数据。
let $ = {
ajax: function (option) {
// 1.参数处理:方便用户调用,代码也可以更简洁
// 1.1 如果没有传递请求方式,默认以Get方式来传递
let type = option.type || 'get'
// url,要求传递
let url = option.url
// 参数,如果没有传递参数,那么默认为空字符串
let data = option.data
// 处理函数
let success = option.success
// 2.创建异步对象
let xhr = new XMLHttpRequest()
// 3.异步对象发起请求
// 3.1 设置请求行,如果是Get方式,在有参数的时候需要在url后面拼接参数
if (type == 'get') {
url = url + '?' + data
data = null
}
xhr.open(type, url)
// 3.2 设置请求头
if (type == 'post') {
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
}
// 3.3 设置请求体,post如果有参数,需要在请求体中传递
xhr.send(data)
// 4. 异步对象接收响应
xhr.onload = function () {
// 4.1 接收返回数据,转换
let res = JSON.parse(xhr.response)
// 4.2 调用用户传入的回调函数
success(res)
}
}
}
2. 知识补充:
2.1 扩展功能-数据类型
传入数据类型,让ajax函数将服务器返回的数据进行类型转换
// 数据类型
let dataType = option.dataType || 'text/html'
----------------------------------------------
//根据dataType进行数据的转换
// 4. 异步对象接收响应
xhr.onload = function () {
// 4.1 接收返回数据,转换
let res = null
if (dataType.toLowerCase() == 'json') {
res = JSON.parse(xhr.response)
} else if (dataType.toLowerCase() == 'xml') {
res = xhr.responseXML
} else {
res = xhr.response
}
// 4.2 调用用户传入的回调函数:因为数据如何处理不由封装函数来决定,而是由调用者决定
success && success(res)
}
2.2 扩展功能-参数的格式
用户传递参数的时候可以传入字符串,也可以传递对象
ajax工具函数应该对用户所传递的参数进行判断,如果是对象,将其转换为key=value&key=value的格式
// 参数,如果没有传递参数,那么默认为空字符串
let data = this.getParams(option.data)
-------------------------------------------
getParams: function (data) {
// 如果没有传递任何的参数,直接返回字符串
if (data) {
// 如果是对象{name:'jack',age:20} >>> name=jack&age=20&
if (typeof data == 'object') {
let str = ''
for (let key in data) {
str = str + key + '=' + data[key] + '&'
}
// name=jack&age=20& >>> name=jack&age=20
return str.substr(0, str.length - 1)
} else {
return data
}
// 否则,直接返回
} else {
return ''
}
}
2.3 逻辑运算符:与、或
||:逻辑或:如果满足第一个就不会再执行第二个,如果第一个为false就继续执行第二个
&&:逻辑与:只有所有条件都满足才为true,有一个为False停止运行,返回fasle
2.4 回调函数
回调函数就是传递一个参数化的函数,就是将这个函数作为一个参数传到另一个主函数里面,当那一个主函数执行之后,再执行传进去的作为参数的函数。换个说法也就是被作为参数传递到另一个函数(主函数)的那个函数就叫做 回调函数。
function b() {
console.log('我是函数b');
}
function go(fn) { // go函数接收一个参数,fn
console.log('我是函数go');
// console.log(fn);
fn();
}
go(b);
// 回调函数:一个函数的形参要求接收一个外部函数,这个外部函数就变成了回调函数,可以在函数内部调用外部的回调函数
// go中的形参fn,要求接收一个外部函数:调用传入b,b就是回调函数,内部通过fn触发了b函数
3. 完整代码实现:
var $ = {
getParams: function (data) {
// 如果没有传递任何的参数,直接返回字符串
if (data) {
// 如果是对象{name:'jack',age:20} >>> name=jack&age=20
if (typeof data == 'object') {
let str = ''
for (let key in data) {
str = str + key + '=' + data[key] + '&'
}
// name=jack&age=20&
return str.substr(0, str.length - 1)
} else {
return data
}
// 否则,直接返回
} else {
return ''
}
},
// 请求方式:option.type
// 请求url: option.url
// 请求参数:option.data
// 请求数据的类型:option.dataType: json xml text
// 请求成功之后的数据处理函数: option.success
ajax: function (option) {
// 1.参数处理:方便用户调用,代码也可以更简洁
// 1.1 如果没有传递请求方式,默认以Get方式来传递
let type = option.type || 'get'
// url,要求传递
let url = option.url
// 参数,如果没有传递参数,那么默认为空字符串
let data = this.getParams(option.data)
// 数据类型
let dataType = option.dataType || 'text/html'
// 处理函数
let success = option.success
// 2.创建异步对象
let xhr = new XMLHttpRequest()
// 3.异步对象发起请求
// 3.1 设置请求行,如果是Get方式,在有参数的时候需要在url后面拼接参数
if (type.toLowerCase() == 'get' && data) {
url = url + "?" + data
data = null
}
xhr.open(type, url)
// 3.2 设置请求头
if (type.toLowerCase() == 'post') {
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
}
// 3.3 设置请求体,post如果有参数,需要在请求体中传递
xhr.send(data)
// 4. 异步对象接收响应
xhr.onload = function () {
// 4.1 接收返回数据,转换
let res = null
if (dataType.toLowerCase() == 'json') {
res = JSON.parse(xhr.response)
} else if (dataType.toLowerCase() == 'xml') {
res = xhr.responseXML
} else {
res = xhr.response
}
// 4.2 调用用户传入的回调函数:因为数据如何处理不由封装函数来决定,而是由调用者决定
success && success(res)
}
// return xhr.response
}
}
2.JQuery中的Ajax
2.1 jq中常用ajax属性
(重点掌握加粗属性)
$.ajax({}) 可配置方式发起Ajax请求
-
url 接口地址 *
-
type 请求方式 *
-
timeout 请求超时
-
dataType 服务器返回格式 *
-
data 发送请求数据 *
-
beforeSend:function () {} 请求发起前调用
-
success 成功响应后调用 *
-
error 错误响应时调用 :就是请求失败后的回调
-
complete 响应完成时调用(包括成功和失败)
$.get(url,data,callback,dataType) 以GET方式发起Ajax请求
$.post(url,data,callback,dataType) 以POST方式发起Ajax请求
$(‘form’).serialize()序列化表单(即格式化key=val&key=val)
2.2 使用JQ的ajax
直接引入jq的script文件,通过$.ajax({}) 发起Ajax请求
error 请求失败后的回调
设置超时,单位是毫秒,当响应时间超出了设置的超时时间,就会报错–意味着当前请求是失败的
$.ajax({
timeout: 2000,
// error:请求失败后的回调
error: function (err) {
console.log(err)
if (err.statusText == "timeout") {
alert('请求超时,请重试')
}
}
})
beforeSend:function () {} 请求发起前调用
在请求发送之前触发,如果这个函数中返回了false则会中止本次请求
只写return还是会发请求,只有写return false才会中止本次请求
这个函数有一个重要的参数,就是封装函数内部所创建的异步对象
beforeSend: function (xhr) {
if (name.trim().length == 0) {
console.log('aa')
alert('请输入用户名')
return false
}
}
complete 请求完成时调用(包括成功和失败)
主要的使用场景是进行全局成员的重置
complete: function () {
console.log('成功的执行了')
}
$(‘form’).serialize()序列化表单
serialize可以获取指定表单中 拥有name属性的 表单元素的 value值,生成key=value&key=value这种格式。要求表单元素的name一定要参照后台接口文件的说明
$('form').serialize()
GET方式发起Ajax请求
$.get(请求url,传递的参数,成功的回调函数,返回数据的格式)
$.get(url,data,success,dataType)
$.get('http://127.0.0.1:3002/getjson', function (res) {
console.log(res)
})
POST方式发起Ajax请求
$.post(请求url,传递的参数,成功的回调函数,返回数据的格式)
$.post(url,data,success,dataType)
$.post('http://127.0.0.1:3002/doRegister', $('form').serialize(), function (res) {
console.log(res)
}, 'json')