1、 Ajax 基础
1.1 传统网站中存在的问题
1、网速慢的情况下,页面加载时间长,用户只能等待
2、表单提交后,如果一项内容不合格,需要重新填写所有表单内容
3、页面跳转,重新加载页面,造成资源浪费,增加用户等待时间
1.2 Ajax 概述
1、Ajax
的全称是 Asynchronous Javascript And XML
(异步 JavaScript 和 XML)
2、Ajax的原理简单来说通过XMLHttpRequest
对象来向服务器发异步请求,从服务器获得数据,然后用JavaScript来操作DOM而更新页面
3、XMLHttpRequest
(简称xhr)是浏览器提供的Javascript 对象,通过它,可以请求服务器上的数据资源。jQuery中的Ajax函数,就是基于xhr对象封装出来的。
流程图:
浏览器可以发送HTTP请求后,接着做其他事情,等收到XHR返回来的数据再进行操作
1.3 Ajax 应用场景
如:
1、用户名检测:注册用户时,通过 ajax 的形式,动态检测用户名是否被占用
2、搜索提示:当输入搜索关键字时,通过 ajax 的形式,动态加载搜索提示列表
3、数据分页显示:当点击页码值的时候,通过 ajax 的形式,根据页码值动态刷新表格的数据
4、数据的增删改查:数据的添加、删除、修改、查询操作,都需要通过 ajax 的形式,来实现数据的交互
2、Ajax 运行原理及实现
2.1 Ajax 运行原理
Ajax 相当于浏览器发送请求与接收响应的代理人,以实现在不影响用户浏览页面的情况下,局部更新页面数据,从而提高用户体验。
2.2 Ajax 实现步骤
实现 Ajax异步交互需要服务器逻辑进行配合,需要完成以下步骤:
1、创建 Ajax的核心对象 XMLHttpRequest对象
2、通过 XMLHttpRequest 对象的 open() 方法与服务端建立连接
3、构建请求所需的数据内容,并通过XMLHttpRequest 对象的 send() 方法发送给服务器端
4、通过 XMLHttpRequest 对象提供的 onreadystatechange 事件监听服务器端的通信状态
5、接受并处理服务端向客户端响应的数据结果
6、将处理结果更新到 HTML页面中
1、创建 Ajax 对象
使用 XMLHttpRequest 构造函数实例化创建一个 xhr(“小黄人”)。
var xhr = new XMLHttpRequest();
2、告诉 Ajax 请求方式以及请求地址
以何种方式发送请求,向哪发送请求。
// xhr.open('method', 'url')
xhr.open('get', 'http://www.example.com');
3、发送请求
xhr.send();
4、获取服务器端给与客户端的响应数据
响应受到网络环境的影响,发送请求以后不能直接去接收数据(例如网络拥挤导致服务器延迟响应),而是要使用 onreadystatechange
事件监听服务器端的通信状态,主要监听的属性为XMLHttpRequest.readyState
。responseText
是服务器响应的数据内容。
xhr.onreadystatechange = function () {
// 当 ajax 状态码为 4,意味着服务器成功接收到请求
// 当 http 状态码为 200,意味着客户端成功接收到数据,交易成功
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
}
关于XMLHttpRequest.readyState
属性有五个状态,如下图显示
客户端(浏览器)向服务器端发起请求,服务器接收到请求信息,然后向客户端返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。
HTTP常见状态码:
200:请求成功。
301:资源被永久转移到其他 URL
404:请求的资源不存在
500:服务器端内部错误
2.3 JSON
1、JSON的概念
JSON
的英文全称是JavaScript Object Notation,
即“JavaScript
对象表示法”。简单来讲,JSON
就是Javascript
对象和数组的字符串表示法,它使用文本表示一个JS对象或数组的信息,
因此,JSON的本质是字符串。
2、JSON的两种结构
JSON就是用字符串来示Javascript的对象和数组。所以,JSON中包含对象和数组两种结构,通过这两种结构的相互嵌套,可以表示各种复杂的数据结构。
1、对象结构:
对象结构在JSON中表示为{ }括起来的内容。
数据结构为{ key: value, key: value, .. }
的键值对结构。
其中,key 必须是使用英文的双引号包裹的字符串,value 的数据类型可以是数字、字符串、布尔值、null、 数组、对象6种类型。
2、数组结构:
数组结构在JSON中表示为[ ]括起来的内容。
数据结构为[ "java", "javascript", 30, true ..]
。
数组中数据的类型可以是数字、字符串、布尔值、null、 数组、对象6种类型。
2.4 JSON和JS对象的相互转化
1、在真实的项目中,服务器端大多数情况下会以 JSON 对象作为响应数据的格式。
2、当客户端拿到响应数据时,要将 JSON 数据和 HTML 字符串进行拼接,然后将拼接的结果展示在页面中。
3、通过 xhr.getResponseHeader('Content-Type')
可获取服务器响应数据的形式,一般有两种:
1、JSON 对象形式:`application/json`
返回的 `xhr.responseText` 为 JSON 对象字符串,需要转换为 JSON 对象。
2、普通字符串形式:`text/hrml`
在 http 请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输。我们往往使用 JSON.parse()
方法将该对象字符串转换为对象。
将 json 字符串转换为JS对象,使用JSON.parse()方法
JSON.parse() // 将 json 字符串转换为json对象
xhr.onload = function () {
var responseText = JSON.parse(xhr.responseText)
console.log(responseText);
}
要实现从JS对象转换为JSON字符串,使用JSON.stringify()方法
var json = JSON.stringify({a:'Hello', b: 'World' });
//结果是' {"a": "Hello", "b":"World"} '
2.5 get请求/post请求带参数
1、GET请求
//get.html
btn.onclick = function () {
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
// 拼接请求参数
var params = 'username=' + nameValue + '&age=' + ageValue;
// 调用open函数
xhr.open('get', 'http://localhost:3000/test?' + params);
// 发送请求
xhr.send();
// 获取服务器端响应的数据
xhr.onreadystatechange = function () {
// 当 ajax 状态码为 4,意味着服务器成功接收到请求
// 当 http 状态码为 200,意味着客户端成功接收到数据,交易成功
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
}
2、POST请求
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('name=zhangsan&age=20');
举例:
// 拼接参数
let params = 'username=' + nameValue + '&age=' + ageValue;
// 设置post请求
xhr.open('post', 'http://localhost:3001/post');
// 设置请求参数格式的类型(post方式必须设置,固定写法)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// post请求的参数写在 send 方法里面
xhr.send(params);
//监听事件
xhr.onreadystatechange = function () {
// 当 ajax 状态码为 4,意味着服务器成功接收到请求
// 当 http 状态码为 200,意味着客户端成功接收到数据,交易成功
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
2.6 两种获取服务器端响应方式的区别
3、封装自己的Ajax
1、简单封装一个 GET Ajax 请求函数
function ajax(options) {
let xhr = new XMLHttpRequest();
xhr.open(options.type, options.url);
xhr.send();
xhr.onload = function () {
//把服务器响应的数据xhr.responseText传给success函数
options.success(xhr.responseText);
}
}
//使用部分
ajax({
type: 'get',
url: 'http://localhost:3001/first',
// 通过 success 函数接收返回的响应数据,并进行下一步处理
success: function (data) {
console.log(data);
}
});
2、完整版本
//封装一个ajax请求
function ajax(options) {
//创建XMLHttpRequest对象
const xhr = new XMLHttpRequest()
//初始化参数的内容
options = options || {}
options.type = (options.type || 'GET').toUpperCase()
options.dataType = options.dataType || 'json'
const params = options.data
//发送请求
if (options.type === 'GET') {
xhr.open('GET', options.url + '?' + params, true)
xhr.send(null)
} else if (options.type === 'POST') {
xhr.open('POST', options.url, true)
xhr.send(params)
//接收请求
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
let status = xhr.status
if (status >= 200 && status < 300) {
options.success && options.success(xhr.responseText, xhr.responseXML)
} else {
options.fail && options.fail(status)
}
}
}
}
使用方式如下
ajax({
type: 'post',
dataType: 'json',
data: {},
url: 'https://xxxx',
success: function(text,xml){//请求成功后的回调函数
console.log(text)
},
fail: function(status){请求失败后的回调函数
console.log(status)
}
})
4、FormData
4.1 H5新增FormData 对象
H5新增FormData 对象,模拟表单操作,在有多个参数的 Ajax 请求中,例如名字、密码、年龄、性别等,都要使用 DOM 获取元素,然后又要按照规则拼接参数。传统 Ajax 也不能传送二进制文件。使用 FormData 对象可以解决这些问题。
FormData 的作用:
1、模拟 HTML 表单,相当于将 HTML 表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式。
2、异步上传二进制文件
4.2 FormData 对象的使用
1、准备 HTML 表单
<form id="form">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="button"/>
</form>
2、将 HTML 表单转化为 FormData 对象
var form = document.getElementById('form');
var formData = new FormData(form);
3、提交表单对象
var xhr = new XMLHttpRequest();
xhr.open('post', 'http://localhost:3001/post');
xhr.send(formData);
注意:
FormData
对象不能用于 get 请求,因为对象需要被传递到 send
方法中,而 get
请求方式的请求参数只能放在请求地址的后面。
4.3 FormData 二进制文件上传
<input type="file" id="file"/>
var file = document.getElementById('file')
// 当用户选择文件的时候
file.onchange = function () {
// 创建空表单对象
var formData = new FormData();
// 将用户选择的二进制文件追加到表单对象中
formData.append('attrName', this.files[0]);
// 配置ajax对象,请求方式必须为post
xhr.open('post', 'www.example.com');
xhr.send(formData);
}
4.4 FormData 文件上传展示
// 当用户选择文件的时候
file.onchange = function () {
// 文件上传过程中持续触发onprogress事件
xhr.upload.onprogress = function (ev) {
// 当前上传文件大小/文件总大小 再将结果转换为百分数
// 将结果赋值给进度条的宽度属性
bar.style.width = (ev.loaded / ev.total) * 100 + '%';
}
}
4.5 FormData 文件上传图片即时预览
xhr.onload = function () {
var result = JSON.parse(xhr.responseText);
var img = document.createElement('img');
img.src = result.src;
img.onload = function () {
document.body.appendChild(this);
}
}
5、axios
1、什么是axios
1、axios专注于网络数据请求的库。
2、相比于原生的XMLHttpRequest对象,axios 简单易用。
3、相比于jQuery, axios 更加轻量化,只专注于网络数据请求。
2、axios发起GET 请求
语法:
axios.get('url', {params:{/*参数*/}}).then (callback)
具体的请求示例如下:
// 请求的URL地址
var url = 'http://www. liulongbin. top: 3006/api/get '
// 请求的参数对象
var paramsObj = { name: 'zs',age: 20 }
// 调用axios.get() 发起GET请求
axios.get(ur1, { params: paramsObj }).then (function(res) {
// res.data 是服务器返回的数据
var result = res.data
console. log (res)
})
3、axios发起POST请求
语法:
axios.post('url', {params:{/*参数*/}}).then (callback)
直接使用axios发起请求
axios也提供了类似于jQuery中$.ajax()的函数,语法如下:
axios ({
method: '请求类型’,
url: '请求的URL地址',
data: { /*POST数据*/},
params:{ /*GET参数*/}
}).then(callback)
6、同源与跨域
1、同源
如果两个页面拥有相同的协议、域名和端口,那么这两个页面就属于同一个源,其中只要有一个不相同,就是不同源。
同源策略,它是由 Netscape 提出的一个著名的安全策略,现在所有支持 JavaScript 的浏览器都会使用这个策略。
浏览器规定,A网站的JavaScript,不允许和非同源的网站C之间,进行资源的交互
2、跨域
1.同源指的是两个URL的协议、域名、端口一致,
反之,有一项不相同,则是跨域。
2.出现跨域的根本原因:
浏览器的同源策略不允许非同源的URL之间进行资源的交互。
3、浏览器对跨域请求的拦截
浏览器允许发起跨域请求,但是,跨域请求回来的数据,会被浏览器拦截,无法被页面获取到!
4、如何实现跨域数据请求
现如今,实现跨域数据请求,最主要的两种解决方案,分别是JSONP和CORS。
1.JSONP:
出现的早,兼容性好(兼容低版本IE) 。是前端程序员为了解决跨域问题,被迫想出来的一种临时解决方案。缺点是只支持GET求,不支持POST请求。
2.CORS:
出现的较晚,它是W3C标准,属于跨域Ajax请求的根本解决方案。支持GET和POST请求。缺点是不兼容某些低版本的浏览器。