ajax
使用表单提交数据的时候,会刷新页面(跳转页面),为了避免跳转页面,Ajax就出现了
特点:使用Ajax不仅可以与服务器中进行数据交互,还可以在不跳转页面的情况下实现局部页面更新
全称:Asynchronous JavaScript And XML 异步的JS与XML
XML:可扩展标记语言,以前也是进行前后端数据交互的
特点:只要具备文档声明,所有的标签都是自定义的。但是使用XML传递数据的时候,前端解析起来比较麻烦,后端生成文件也是比较麻烦,所以逐渐被json数据代替
使用Ajax
在IE8以上包括高级浏览器他们都支持XMLHttpRequest这个构造函数
在IE8之前他们都支持ActiveXObject这个构造函数
通过构造函数的实例化对象调用某些方法即可发送AJAX请求
// 创建ajax对象
let xhr;
// 高级浏览器--功能检测
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xhr = new ActiveXObject();
} else {
alert('不支持ajax');
}
// 监听状态改变
xhr.onreadystatechange = function() {
// 当全部接收完毕
if (xhr.readyState === 4) {
// 请求成功
if (xhr.status === 200 || xhr.status === 304) {
// 查看数据
console.log(xhr);
console.log(xhr.responseText);
var name = xhr.responseText.getElementByTagName('name')[0].innerHTML;
dom.innerHTML = name;
}
}
}
// 打开连接
xhr.open('GET', `/ickt?username=${username}&password=${password}`, true)
// 发送ajax
// 发送
xhr.send();
var request = new XMLHttpRequest();
request.open('GET', '/xxxx')
request.onreadystatechange = function() {
if (request.readyState === 4) {
console.log('请求完成')
if (request.response.status >= 200 && request.response.status < 300) {
console.log('请求成功')
} else {}
}
}
request.send()
简化版
var request = new XMLHttpRequest();
request.open('GET', '/xxxxxxx')
request.onload = () => { console.log('请求成功') }
request.send()
Ajax属性方法
onreadyStatechange:该方法会在状态码发生改变的时候执行
readyState:状态码
0:未初始化
1:已经调用open方法
2 已经接收到响应头
3:已经接收一部分响应文本
4:接收全部响应文本
status:服务器的状态码
200 表示成功
304 表示重定向
404 表示文件没有找到
500 服务器内部发生错误
responseText:接收到的响应文本
responseXML:接收的文档对象
open:建立TCP连接
send:发送HTTP请求
setRequestHeader:该方法用于修改请求头,例如:将数据模拟为真正的表单数据
// 模拟表单,修改请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form- urlencoded')
open方法用于建立TCP连接
使用方式:
xhr.open(method, url, bool)
method:本次请求的方式
url: 本次请求的路径(可以携带query数据)
bool: 决定了本次发送请求的时候使用异步或是同步,通常传递true表示异步
jQuery中的Ajax
发送get请求
使用方式:$.get(url, data, callback, dataType)
url: 本次请求的路径(可以携带query数据)
data: 本次请求携带的数据,可以是字符串,可以是对象
callback: 回调函数
dataType: 数据类型,默认是字符串,当我们传递json的时候,将数据转为json格式
转为JSON对象
JSON内置对象中提供了两个方法:parse, stringify (必须满足JSON语法)
parse: 用于将json字符串解析为json对象
stringify: 用于将json对象转为json字符串
eval函数可以将字符串作为代码执行
使用方式:eval('(' + str + ')')
let result = eval('(' + str + ')');
function内置构造函数可以实现将字符串转为对象
传参规则:除了最后一个参数是函数体之外,其它的都是形参
let result = new Function('return (' + str + ')')();
转码与解码
在URL中本身是不允许出现中文字符以及特殊字符的,但是有些时候还必须要用到中文字符以及特殊字符,此时就需要对URL进行转码
转码的使用方式:encodeURIComponent(code)
code:要转码的中文字符
返回值就是转码之后的字符
解码的使用方式:decodeURIComponent(code)
code:被转码之后的字符
返回值解码之后的中文字符
表单序列化
使用ajax发送表单数据,如果表单中的数据结构比较复杂,需要使用表单序列化
jquery中的表单序列化
使用方式:$(form).serialize()
该方法获取指定的form表单中的所有数据
xhr属性
readyState 存有的XMLHttpRequest的状态从0到4发生变化
response 表示服务器的响应内容
responseType 表示服务器返回数据的类型,缺省为空字符串,可取"arraybuffer",
,"blob","document","json","text"共五种类型
responseText 以文本形式返回响应
responseXML 以XML格式返回响应
status 将状态返回为数字(例如,404,200)
statusText 以字符串形式返回状态(例如"Not Found"或"Ok")
timeout 用于指定ajax的超时时长,表示多少毫秒后,如果请求仍然没有得到结果,就会自动终止
upload 属性默认返回一个XMLHttpRequestUpload对象,用于上传资源
status常见状态码
200 Ok,访问正常
301 Moved Permanently,永久移动
302 Move temporarily,暂时移动
304 Not Modified,未修改
307 Temporary Redirect,暂时重定向
401 Unauthorized,未授权
403 Forbidden,禁止访问
404 Not Found,为发现指定网址
500 Internal Server Error,服务器发生错误
xhr方法
open() 用于指定发送HTTP请求的参数
send() 表示实际发出HTTP请求,参数是携带的数据
abort() 取消当前请求
getAllResponseHeaders() 以字符串形式返回完整的HTTP标头集
getResponseHeader(name) 返回指定HTTP标头的值
setRequestHeader(key, value)将标签/值对添加到要发送的HTTP标头
overrideMimeType() 用于强制指定response的MIME类型,即强制修改response的Content-Type
xhr事件
onreadystatechange事件 监听readystate状态改变
onloadstart事件 在ajax请求发送之前触发,触发时机在readyState==1状态之后,2状态之前
onprogress事件 在readyState==3状态时开始触发
onerror事件 在ajax请求出错后执行,通常只在网络出现问题时触发
onbort事件 用来终止已经发出的HTTP请求,取消后,readyState状态将被设置为0
onload事件 onload事件回调方法在ajax请求成功后(readyState==4状态后)触发
onloadend事件 在ajax请求完成后(readyState==4状态后或者readyState==2状态后)触发
ontimeout事件 判断请求超时
请求超时
// 设置请求超时事件
// xhr.timeout = 5000;
var time = Date.now()
// // 监听超时
// xhr.ontimeout = function() {
// console.log(Date.now() - time);
// }
请求中断
// 请求中断
setTimeout(function() {
xhr.abort()
}, 2000)
// 监听请求中断
xhr.onabort = function() {
console.log(Date.now() - time, xhr.readyState);
}
历史记录
在H5中提供了history对象用于操作历史记录的,分别提供了两个方法:
history.pushState(any, title, url)
history.replaceState(any, title, url)
以上两个方法都是改变历史记录列表的
any: 表示数据
title: 新的网页标题
url: 新的网页的url
与之配套的还有一个事件:window.onpopstate事件
该事件会在历史记录发生变化的时候执行
Ajax 2.0
FormData
在AJAX2.0中新增了FormData构造函数
作用:用户快速进行表单序列化
使用方式:
let fd = new FormData(form)
form:原生的form表单元素
参数是可有可无的
如果传递了参数,得到一个fd的实例化对象,我们可以通过其原型中的方法查看内部结构
如果没有传递参数,得到的是一个空的对象,我们可以调用原型中的方法添加数据
forEach
使用方式:
fd.forEach(fn)
fn:处理函数
有三个参数
第一个参数:输入的内容
第二个参数:输入框name值
第三个参数:FormData对象
this指向全局作用域
append与delete
append:该方法用于添加数据的
使用方式:fd.append(key, value)
key: name值
value: 是数据
delete:该方法用于删除数据中的某一项
使用方式:fd.delete(key)
key:数据名称
get与getAll
get:该方法用于获取某一项数据
使用方式:fd.get(key)
key:对应的name值
返回值就是获取到数据
getAll:该方法用于获取某个name字段的所有数据
使用方式:fd.getAll(key)
key:对应的name值
返回值是一个数组
has与set
has:该方法用判断是否包含某个属性
使用方式:fd.has(key)
key:对应的name值
返回值是布尔值
如果存在,返回true
如果不存在,返回false
set:该方法用于设置内容的,与append方法不同的是,set方法会覆盖掉之前已经添加的数据
使用方式:fd.set(key, value)
key: 对应的name值
value: 数据
####实现ajax
// 发送请求
ajax({
url: '/demo',
method: 'POST',
data: { username, password },
headers: {
// 模拟表单
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(data => console.log(data))
.catch(err => console.log(err))
}
// 实现ajax
function ajax(options) {
// 适配参数
options = Object.assign({
url: '',
method: 'GET',
data: '',
headers: {}
}, options)
// 适配data属性
if (typeof options.data !== 'string') {
// 适配
let str = '';
// 解析data对象
for (let key in options.data) {
str += `&${key}=${options.data[key]}`;
}
// 更新data属性
options.data = str.slice(1);
}
// 如果是get请求,数据放在url上
if (options.method.toUpperCase() === 'GET') {
// 数据放在url上作为uqery数据
options.url += '?' + options.data;
}
console.log(options);
// 返回promise规范
return new Promise((resolve, reject) => {
// 1 创建ajax对象
let xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xhr = new ActiveXObject();
} else {
alert('该浏览器不支持ajax');
return reject('该浏览器不支持ajax');
}
// 2 监听状态变化
xhr.onreadystatechange = function() {
// 判断状态
if (xhr.readyState === 4) {
// 判断状态码
if (xhr.status === 200 || xhr.status === 304) {
// 成功
resolve(JSON.stringify(xhr.responseText))
} else {
reject('请求失败');
}
}
}
// 3 打开请求
xhr.open(options.method, options.url, options.async);
// 更改请求头,模拟表单的形式
if (options.headers) {
// 遍历配置
for (let key in options.headers) {
// 修改请求头
xhr.setRequestHeader(key, options.headers[key])
}
}
// 4 发送数据
xhr.send(options.data);
})
}