- 原生ajax
- 服务端Node.js
- jQuery
- Axios
案例
express框架基础介绍
通过require引入
1
| const express = require('express');
|
服务端node.js程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const { response } = require('express'); const express = require('express');
const app = express();
app.get('/server',(request,response)=>{ response.setHeader('Access-Control-Allow-Origin','*');
response.send('Hello Ajax'); })
app.listen(8000,()=>{ console.log("服务已启动");
})
|
原生ajax
通过 创建 XMLHttpRequest()对象创建
1
| const xhr = new XMLHttpRequest();
|
创建之后, 需要开启, 然后发送请求
1 2 3
| xhr.open('GET','http://127.0.0.1:8000/server');
xhr.send();
|
想要处理服务端返回的结果, 要绑定事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| xhr.onreadystatechange = function(){ if(xhr.readyState===4){
if(xhr.status>=200 &&xhr.status<300){
console.log(xhr.status); console.log(xhr.statusText); console.log(xhr.getResponseHeader); console.log(xhr.getAllResponseHeaders); console.log(xhr.response);
} } }
|
Ajax设置请求参数
正常设置请求参数, 就是放在请求url后面
1
| xhr.open('GET','http://127.0.0.1:8000/server?a=100&b=200&c=300');
|
发送post请求
open的时候把参数设置为post
1
| xhr.open('POST','http://localhost:8000/server');
|
服务端开启接受就可以
1 2 3 4 5
| app.post('/server',(request,response)=>{ response.setHeader('Access-Control-Allow-Origin','*');
response.send('Hello Ajax POST'); })
|
POST请求设置请求体
需要在send()
里面设置
1
| xhr.send('a=100&b=200&c=300');
|
设置请求头信息
使用setRequestHeader()
方法
1
| xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
|
也可以自定义
1
| xhr.setRequestHeader('name','123456');
|
但是需要服务端设置
1
| response.setHeader('Axess0-Control-Allow_Headers','*');
|
但是因为还会发一个OPTION请求, 所以服务端还需要接受OPTION请求才行
将接收方法改成all
1 2 3 4 5
| app.all('/server',(request,response)=>{ response.setHeader('Access-Control-Allow-Origin','*'); response.setHeader('Axess0-Control-Allow_Headers','*'); response.send('Hello Ajax POST'); })
|
服务端响应JSON
使用JSON
1 2 3 4 5 6
| const data ={ name: 'klen' };
let str = JSON.stringify(data); response.send(str);
|
前端解析也是使用JSON
中的parse()
方法
1 2
| let data = JSON.parse(xhr.response); console.log(data);
|
以上是手动转换json对象, 也可以开启自动转换
1
| xhr.responseType = 'json';
|
这样前段直接获取就好了
1
| result.innerHTML = xhr.response.name;
|
NodeMon自动重启工具
安装nodemon
使用nodemon启动服务器文件
请求超时和网络异常处理
服务端可以设置延时响应:
1 2 3 4 5 6 7
| app.get('/delay',(request,response)=>{ response.setHeader('Access-Control-Allow-Origin','*'); setTimeout(()=>{ response.send('延时响应'); },3000); });
|
客户端可以设置超时时间
如果一定时间内没有返回结果, 请求就取消
也可以加回调函数
1 2 3
| xhr.ontimeout = function(){ alert("网络异常"); }
|
网络异常也可以设置回调
1 2 3
| xhr.onerror = function(){ alert("你的网络出了一些问题"); }
|
手动取消请求
调用abort方法
1 2 3 4
| cancel.onclick = function(){ xhr = new XMLHttpRequest(); xhr.abort(); }
|
请求重复发送问题
可以判断请求是否正在发送, 如果正在发送, 取消当前正在发送到请求, 重新发送一样的请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| let xhr = null; let isSending = false; send.onclick = function(){ if(isSending){ xhr.abort(); } xhr = new XMLHttpRequest(); isSending = true; xhr.open('get','http://localhost:8000/delay') xhr.send(); xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ isSending = false; } } }
|
jQuery 使用Ajax
BootCDN
使用bootcdn引入在线jQuery库
1
| <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
|
然后使$.get()
发送get类型的ajax请求
1 2 3 4 5
| $('button').eq(0).click(function(){ $.get('http://localhost:8000/jquery-server',{a:100,b:200},function(data){ console.log(data); }); });
|
$.post()
请求也是同理,
$.get()
和$.post()
里面还可以传递第四个参数, 'json'
, 代表讲响应内容转换为json
1 2 3 4 5
| $('button').eq(0).click(function(){ $.get('http://localhost:8000/jquery-server',{a:100,b:200},function(data){ console.log(data); },'json'); });
|
这样当服务端发送json数据都时候就可以自动转换成对象
1 2 3
| const data = {name:'klen'}; response.send(JSON.stringify(data));
|
通用方法
$.ajax
是个jQuery通用的发送ajax的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| $('button').eq(2).click(function(){ $.ajax({ url: 'http://localhost:8000/jquery-server', type: 'post', data: {a:100,b:200}, dataType: 'json', success: function(data){ console.log(data); } }); });
|
还有很多其他参数, 比如失败回调函数error:
, 可以处理包括超时, 网络异常等问题. 还有header:
设置请求头
Axios
引入js包
1
| <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
|
GET
使用axios.get( url[, config])
发送get请求, 里面一般封装两个参数, 请求url和请求参数对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| axios.defaults.baseURL = 'http://localhost:8000';
btn[0].onclick = function () { axios.get('/axios-server',{ params:{ id : 100, vip: 7 }, headers:{ name: 'atguigu', age:20 } }).then(value => { console.log(value); }); }
|
可以使用axios.defaults.baseURL
配置根地址, 这样方便书写
不同于jQuery的是, 处理返回响应axios不是使用success回调函数, 而是.then
, 基于promise
value
里面封装了包括请求信息, 头信息, 响应数据等等.
服务端的JSON数据自动转换成了对象.
POST
使用axios.post( url[, data[, config]])
发送post请求, 有三个参数, 第二的参数是数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| axios.post('/axios-server', { username: 'admin', password: 'admin' }, { params: { id: 200, vip: 9 }, headers: { name: 'atguigu', age: 20 },
});
|
通用请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| axios({ url: '/axios-server', method: 'post', params:{ vip:10, level:30,
}, headers:{ a:100, b:200 }, data:{ username:'admin', password:'admin' }
}).then(value =>{ console.log(value); console.log(value.status); console.log(value.statusText); console.log(value.headers); console.log(value.data); });
|
fetch()
函数
用于发起获取资源的请求, 返回结果是一个promise, 在请求响应后被解析传回response对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| btn.onclick = function(){ fetch('http://localhost:8000/fetch-server?vip=10',{ method:'POSt', headers:{ name: 'klen' }, body: 'username=admin&password=admin' }).then(response => { return response.json();
}).then(response => { console.log(response); }); }
|
跨域
违背同源策略就是跨域
同源策略
(Same-Orgin Policy)最早由Netscape公司提出, 是一种浏览器的安全策略.
同源: 协议, 域名, 端口号, 必须完全相同
AJAX默认遵循同源策略
服务器的增加, 就容易形成跨域
jsonp
原理
借助script标签实现跨域, 因为script标签本身就具备跨域特性, 只支持get请求
如果在客户端使用<script>
对服务器发送请求
1
| <script src="localhost:8000/jsonp-server"></script>
|
而服务端直接返回的是字符串形式的代码
1
| response.send('console.log(hello)');
|
这样字符串里面的代码会被返回且执行
服务器返回代码, 也可以调用客户端中的函数,
1 2 3 4 5
| const data = { name:"klen" } const str = JSON.stringify(data); response.end(`handle(${str})`);
|
原生jsonp
在客户端创建一个handle函数
1 2 3 4 5
| function handle(data){ input.style.border = "solid 1px #f00"; p.innerHTML = data.msg; }
|
然后为<input>
绑定事件
使用创建script的方法发送请求
1 2 3 4 5 6 7 8 9 10 11
| const input = document.querySelector('input');
input.onblur = function(){ let username = this.value; const script = document.createElement('script'); script.src = 'http://localhost:8000/check-username'; document.body.appendChild(script); }
|
而服务端调用客户端函数
1 2 3 4 5 6 7 8 9 10
| app.all('/check-username',(request,response)=>{
const data = { exist: 1, msg: 'username already exist' } let str = JSON.stringify(data); response.end(`handle(${str})`); });
|
jQuery 发送 jsonp
callback=?为必须参数
1 2 3 4 5 6 7 8 9 10
| $('button').eq(0).click(function(){ $.getJSON('http://localhost:8000/jquery-jsonp-server?callback=?',function(data){ $('#result').html(` 名称: ${data.name}<br> city: ${data.city}
`)
}) })
|
服务端:
1 2 3 4 5 6 7 8 9 10 11
| app.all('/jquery-jsonp-server',(request,response)=>{
const data = { name: 'klen', city: ['Beijing','Shanghai','Guangzhou'] } let str = JSON.stringify(data); let cb = request.query.callback; response.end(`${cb}(${str})`); });
|
CORS
Cross-Origin-Recource-Sharing
官方的跨域解决方案
不用再客户端做任何特殊操作, 全部在服务区中进行处理, 设置响应头就可以
支持get, post请求
服务端设置响应头:
1 2 3
| response.setHeader('Access-Control-Allow-Origin',"*"); response.setHeader('Access-Control-Allow-Headers',"*"); response.setHeader('Access-Control-Allow-Method',"*");
|
还有很多其他响应头可以设置