看这篇文章前,你的小脑袋瓜子 想一想
ajax
和axios
他们有什么区别?他们能做什么?要带着问题来看,这样会事半功倍
一、Ajax
注意事项:本Ajax中的代码片段 发起的请求 都是自己本地文件夹中的app.js接口,我会在Ajax 章节的最后附上源文件。
Ajax 全称(Asynchronous JavaScript and XML)是用于在发送请求的时候 无刷新发送请求,也就是说 用JavaScript执行异步的请求
如果仔细观察一个Form的提交,你就会发现,一旦用户点击“Submit”按钮,表单开始提交,浏览器就会刷新页面,然后在新页面里告诉你操作是成功了还是失败了。如果不幸由于网络太慢或者其他原因,就会得到一个404页面。
这就是Web的运作原理:一次HTTP请求对应一个页面。
如果要让用户留在当前页面中,同时发出新的HTTP请求,就必须用JavaScript发送这个新请求,接收到数据后,再用JavaScript更新页面,这样一来,用户就感觉自己仍然停留在当前页面,但是数据却可以不断地更新。
1.1 ajax入门
<script type="text/javascript">
//1、创建Ajax对象
var xhr = new XMLHttpRequest()
//2、告诉Ajax对象要向哪里发送请求,以什么方式发送请求
//01、请求方式 02请求地址
// 向接口使用get请求方式 请求地址为localhost:4000/frist
//这里的get 是有接口后端 定义的
xhr.open('get','http://localhost:4000/frist');
//3、发送请求
xhr.send();
//4、获取服务器端响应到客户端的数据
xhr.onload = function(){
//打印服务器端返回来的数据 就是Hello ajax
console.log(xhr.responseText)
}
</script>
接口
// 对应01html文件
//接收到客户端的请求
app.get('/frist',(req,res) =>{
// 并返回一个Hello ajax
res.send('Hello ajax');
})
可以看到 我这个是启动了服务器 http://localhost:4000/01.入门.html
访问的这个文件,切记!!! 不能直接打开HTML文件
1.2 处理服务器端返回的JSON数据
<script type="text/javascript">
//1、创建Ajax对象
var xhr = new XMLHttpRequest()
//2、告诉Ajax对象要向哪里发送请求,以什么方式发送请求
//01、请求方式 02请求地址
xhr.open('get','http://localhost:4000/responseDate');
//3、发送请求
xhr.send();
//4、获取服务器端响应到客户端的数据
xhr.onload = function(){
//将json字符串转换为JSON对象
var responseText = JSON.parse(xhr.responseText)
console.log(responseText)
//将获取到数据 进行标签的拼接
<!-----------一般不会使用这种拼接 仅供演示看---------------->
var str = '<h2>'+responseText.name+'</h2>'
// 获取DOM元素 将拼接的str 显示到页面上
document.body.innerHTML = str;
}
</script>
接口:
app.get('/responseDate',(req,res) =>{
res.send({"name":"xiaohu同学"});
})
1.3 传递get 请求参数
<p>
<input type="text" id="username">
</p>
<p>
<input type="text" id="age">
</p>
<p>
<input type="button" value="提交" id="btn">
</p>
<script type="text/javascript">
//获取按钮元素
var btn = document.getElementById('btn');
//获取姓名文本框
var username = document.getElementById('username');
//获取年龄文本框
var age = document.getElementById('age');
//为按钮添加点击事件
//点击后 发生Ajax 请求
btn.onclick = function(){
//创建ajax对象
var xhr = new XMLHttpRequest();
//获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
//拼接请求参数
var params = 'username='+nameValue +'&age='+ageValue;
//配置ajax对象
xhr.open('get','http://localhost:4000/get?'+params);
//发送请求
xhr.send();
//获取服务器端响应的数据
xhr.onload = function () {
console.log(xhr.responseText)
}
}
</script>
接口:
app.get('/get',(req,res) =>{
//使用req.query来接收客户端传递到服务器端的get请求参数
//并使用req.send来响应给客户端
res.send(req.query);
})
1.4 传递post请求参数
<p>
<input type="text" id="username">
</p>
<p>
<input type="text" id="age">
</p>
<p>
<input type="button" value="提交" id="btn">
</p>
<script type="text/javascript">
//获取按钮元素
var btn = document.getElementById('btn');
//获取姓名文本框
var username = document.getElementById('username');
//获取年龄文本框
var age = document.getElementById('age');
//为按钮添加点击事件
btn.onclick = function(){
//创建ajax对象
var xhr = new XMLHttpRequest();
//获取用户在文本框中输入的值
var nameValue = username.value;
var ageValue = age.value;
//拼接请求参数
var params = 'username='+ nameValue +'&age='+ageValue;
//配置ajax对象
xhr.open('post','http://localhost:4000/post');
//设置请求参数的格式的类型(post请求必须要设置)
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//发送请求
xhr.send(params);
//获取服务器端响应的数据
xhr.onload = function () {
console.log(xhr.responseText)
}
}
</script>
1.5 传递Json请求参数
<script type="text/javascript">
//1、创建Ajax对象
var xhr = new XMLHttpRequest()
//2、告诉Ajax对象要向哪里发送请求,以什么方式发送请求
//01、请求方式 02请求地址
xhr.open('post','http://localhost:4000/json');
//同请求头告诉服务器端客户端向服务器端传递的请求参数的格式是什么
xhr.setRequestHeader('Content-Type','application/json')
//要转换为JSON字符串的格式进行传递
//JSON.stringify() 将json对象转换为json字符串
//3、发送请求
xhr.send(JSON.stringify({name:'lisi',age:18}));
//4、获取服务器端响应到客户端的数据
xhr.onload = function(){
console.log(xhr.responseText)
}
</script>
接口:
app.post('/json', (req, res) => {
res.send(req.body)
})
1.6 根据状态码来获取服务器响应数据
<script type="text/javascript">
//1、创建Ajax对象
var xhr = new XMLHttpRequest()
//0 状态码为0 已经创建了对象,但是没有对ajax对象进行配置
console.log(xhr.readyState);//当前打印为0
//1 已经对ajax对象配置,但是还没有发送请求
xhr.open('get','http://localhost:4000/readystate');
console.log(xhr.readyState);//当前打印为1
xhr.onreadystatechange = function () {
//2 请求已经送到
//3 已经接收到服务器端
//4 服务器端的响应数据已经接收完成
console.log(xhr.readyState)//打印结果为2,3,4
//对ajax状态码进行判断
//如果状态码的值为4就代表数据已经接收完成了
if (xhr.readyState == 4) {
//等于4 就接收服务器返回过来的 hello
console.log(xhr.responseText);
}
}
xhr.send();
</script>
接口
app.get('/readystate', (req, res) => {
res.send('hello')
})
1.7 Ajax错误处理
<button id="btn">发送ajax请求</button>
<script type="text/javascript">
//获取Dom结构
var btn =document.getElementById('btn');
//绑定点击事件
btn.onclick = function () {
var xhr = new XMLHttpRequest()
//2、告诉Ajax对象要向哪里发送请求,以什么方式发送请求
//01、请求方式 02请求地址
xhr.open('get','http://localhost:4000/error');
//3、发送请求
xhr.send();
//4、获取服务器端响应到客户端的数据
xhr.onload = function(){
//打印服务器返回来的结果
console.log(xhr.responseText);
//判断 当服务器返回的状态码为400
if(xhr.status == 400){
//弹出提示文字
alert('请求出错')
}
}
//当网络中断时触发error事件
xhr.onerror = function () {
alert('网络中断无法发送请求')
}
}
</script>
接口
//方式为get 请求路径为‘/error’
app.get('/error', (req, res) => {
//手动指定状态码为400
res.status(400).send('not ok')
})
1.8 Ajax异步请求
看下面这部分代码 思考一下打印的顺序
<script type="text/javascript">
//1、创建Ajax对象
var xhr = new XMLHttpRequest()
//2、告诉Ajax对象要向哪里发送请求,以什么方式发送请求
//01、请求方式 02请求地址
xhr.open('get','http://localhost:4000/frist');
//3、发送请求
xhr.send();
//4、获取服务器端响应到客户端的数据
xhr.onload = function(){
console.log('2');
console.log(xhr.responseText)
}
console.log('1');
</script>
接口
app.get('/frist', (req, res) => {
res.send('Hello ajax')
})
Ajax 是异步的任务,在执行的时候 会先执行同步的任务
console.log('1')
,当同步任务执行完成后,才会执行异步的任务Ajax里面的console.log('2')
/console.log(xhr.responseText)
---------------------------分割线------------------------------------------
2.1 向非同源的发起Ajax请求
这个场景 在业务开发中会有用到
什么是非同源呢?
1、端口、域名、协议 这3个有一个不同 就是非同源的
2、相反 就是同源的 我们上述的1.1——1.9 都是在本地起的服务,发起的请求
3、下面的案例 我会启动两个服务器 分别是s1/s2
s1 localhost:3000
s2 localhost:3001
S1文件夹里面的index.html
<script type="text/javascript" src="/js/ajax.js"></script>
<script type="text/javascript">
ajax({
url: 'http://localhost:3001/test',
type: 'get',
success: function (result) {
console.log(result);
}
})
</script>
S2文件的 app.js接口文件
app.get('/test', (req, res) => {
const result = 'fn({name:"小hu同学"})';
res.send(result)
});
可以看到我们这里 请求成功了
2.2 使用jsonp向非同源服务器请求数据
S1 html文件
<button id="btn">
点我发送请求
</button>
<script>
function fn(data) {
console.log('客户端的fn函数被调用了');
console.log(data)
}
</script>
<!-- 1、将非同源服务器端的请求地址写在script标签的src属性中 -->
<script>
//获取按钮
var btn = document.getElementById('btn')
btn.onclick = function () {
//创建script标签
var script = document.createElement('script');
//设置src属性
script.src = 'http://localhost:3001/test?callback=fn'
//将script 追加到页面后面
document.body.appendChild(script);
//为script标签添加onload事件
script.onload = function() {
//将body中的script 标签删除掉
document.body.removeChild(script)
}
}
</script>
S2 app.js
app.get('/better', (req, res) => {
// //接收客户端传递过来的函数名称
// const fnName = req.query.callback
// //将函数名称对应的函数调用代码返回给客户端
// const data = JSON({name:"小hu同学"})
// const result = fnName +'({name:"小hu同学"})';
// setTimeout(() =>{
// res.send(result)
// },1000)
//上面的是使用非jsonp
res.jsonp({
name: 'xiaohu',
age: 20
})
});
2.3 jsonp 请求封装
S1 HTML文件
<button id="btn1">点击发送</button>
<button id="btn2">点击发送2</button>
<script>
//获取按钮
var btn = document.getElementById('btn');
//为按钮添加点击事件
btn1.onclick = function () {
jsonp({
//请求地址 为S2接口地址
url: 'http://localhost:3001/better',
//请求成功后 接收一个参数
success: function (data) {
console.log(123)
console.log(data)
}
})
}
btn2.onclick = function () {
jsonp({
//请求地址
url: 'http://localhost:3001/better',
data:{
name:'小hu',
age:20
},
success: function (data) {
console.log(456789)
console.log(data)
}
})
}
function jsonp(options) {
//动态创建script标签
var script = document.createElement('script')
//拼接字符串的变量
var params = '';
for(var attr in options.data){
params +='&' + attr + '=' + options.data[attr];
}
options.data
//生成一个随机的字符
//最后会变成myJsonp0125886
var fnName ='myJsonp' + Math.random().toString().replace('.','')
//它已经不是一个全局函数了
//我们要想办法将它变成全局函数
window[fnName] = options.success;
//为script标签添加src属性
script.src = options.url + '?callback='+ fnName + params;
//将script 标签追加到页面中
document.body.appendChild(script);
//为script标签添加onload事件
script.onload = function () {
document.body.removeChild(script);
}
}
</script>
2.4 $.ajax的请求方式
$.ajax 是jquery给我们提供的ajax 请求方法可以让我们更方便的去使用ajax 去发送请求
S1 HTML文件
<button id='btn'>发送请求</button>
<!--引入jQuery 的js文件-->
<script src="/js/jquery.min.js"></script>
<script>
$('#btn').on('click',function () {
$.ajax({
//请求方式
type:'get',
//请求地址
url:'/base',
//请求成功后函数被调用
success:function(response){
//response为服务器端返回的数据
//方法内部会自动将json字符串转换为json对象
console.log(response);
},
//请求失败以后函数被调用
error:function(xhr){
console.log(xhr);
}
})
});
</script>
S1 接口
app.get('/base', (req, res) => {
res.send({
name: '小胡',
age: 20
})
})
成功的
失败的(把接口地址修改为了/base1)
(资源文件下载)
二、axios
首先要了解一下 什么是axios?
axios 是一个专注于网络请求的库
axios中文文档
3.1 axios 基础语法
axios({
method:'请求的类型',
url:'请求的URL'
}).then((res)=>{
//.then 在promise里面有说过 用来指定成功之后回调函数
// 形参中的res 是请求成功的结果
})
3.2 axios 发起Get请求
代码示例
<script src="./lib/axios.js"></script>
<script>
//1、调用axios 的返回值是一个promise对象
const res = axios({
method:'GET',
url:'http://www.liulongbin.top:3006/api/getbooks',
//查询URL 查询参数
//get 传参 用params
// 请求只要查询Id 为1的参数
params:{
id:1
},
//post 传参用 data
//请求体参数
data:{}
})
res.then((result) => {
//result 不是真实的数据 result.data 才是真实的数据
console.log(result.data);
}).catch((err) => {
});
</script>
打印result.data的结果
打印result 可以看到 里面的data 才是我们需要的 外面的是axios 给我们套了一层壳
3.3 axios 发起Post 请求
<button id="btn">
发起post请求
</button>
<button id="btnGet">
发起GET 请求
</button>
<script src="./lib/axios.js"></script>
<script>
document.querySelector('#btn').addEventListener('click',async function(params) {
//如果调用某个返回值是promise 的实例 则前面可以添加await
//await 只能用在async 修饰的方法中
const {data} = await axios({
method:'POST',
url:"http://www.liulongbin.top:3006/api/post",
data:{
name:'zs',
age:20
}
})
console.log(data);
})
document.querySelector('#btnGet').addEventListener('click',async function(params) {
// 解构赋值 重命名为res
//1、调用完axios之后 使用async 和awiat 进行简化
//2、使用解构赋值 从axios 封装的对象中,把data 属性解构出来
//3、把解构出来的data属性 使用冒号 进行重命名为res{data:res}
const {data:res} = await axios({
method:'GET',
url:'http://www.liulongbin.top:3006/api/getbooks',
params:{
id:3
}
})
console.log(res.data);
})
</script>
3.4 axios直接发起get和post 请求
<button id="btn">
发起get请求
</button>
<button id="btnPost">发起Post 请求</button>
<script src="./lib/axios.js"></script>
<script>
document.querySelector('#btn').addEventListener('click', async function(params) {
//如果调用某个返回值是promise 的实例 则前面可以添加await
//await 只能用在async 修饰的方法中
// axios.get('Url地址',{
// //Get 参数
// params:{}
// })
const {data:res} = await axios.get('http://www.liulongbin.top:3006/api/getbooks',{
params:{id:1}
})
console.log(res);
})
document.querySelector('#btnPost').addEventListener('click', async function(params) {
// const resPost = await axios.post('http://www.liulongbin.top:3006/api/post',{
// data:{
// name:'zs',
// age:15
// }
// })
const {data:res} = await axios.post('http://www.liulongbin.top:3006/api/post',{
name:'张三',age:15
})
console.log(res);
})
</script>