1、Ajax案例准备
前提:安卓完成node和express。
1.1get/post请求
(1)编写服务端 server.js
注意设置运行跨域
response.setHeader('Access-Control-Allow-Origin', '*');
//1引入express
const express=require('express');
//2创建引用
const app=express();
//3创建路由规则 request对请求报文的封装,response对响应报文封装
app.get('/server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
response.send('hello express');
});
//4监听服务端口
app.listen(8000,()=>{
console.log("8000端口已启用");
});
vscode左侧该文件夹下鼠标右击选择->在集成终端中打开
启动服务:node server.js(服务端文件名)
(2)编写前端页面发送get请求
<style>
#result{
width: 200px;
height: 100px;
border: 1px solid red;
}
</style>
<body>
<button>点击发送</button>
<div id="result"></div>
</body>
<script>
const btn=document.getElementsByTagName('button')[0];
const res=document.getElementById('result');
btn.onclick=function(){
//获取XMLHttpRequest对象
var xhr=new XMLHttpRequest();
//设置请求信息
xhr.open('GET','http://localhost:8000/server');
//发送请求
xhr.send();
//处理响应结果
xhr.onreadystatechange=function(){
//readyState 是 xhr对象中的属性, 表示状态 0 1 2 3 4
if (xhr.readyState===4 && (xhr.status>=200 && xhr.status<300)) {
res.innerHTML=xhr.responseText;
}
}
}
</script>
(3)发送post请求
服务端添加
app.post('/server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
response.send('hello express post');
});
页面部分
<style>
#result{
width: 200px;
height: 100px;
border: 1px solid red;
}
</style>
<body>
<div id="result"></div>
</body>
<script>
const res=document.getElementById('result');
res.addEventListener('mouseover',function(){
//1创建xhr对象
var xhr=new XMLHttpRequest();
//设置参数
xhr.open('POST','http://localhost:8000/server');
//发送请求--带参数
xhr.send('s=100&a=200');
//处理响应结果
xhr.onreadystatechange=function(){
//readyState 是 xhr对象中的属性, 表示状态 0 1 2 3 4
if (xhr.readyState===4 && (xhr.status>=200 && xhr.status<300)) {
res.innerHTML=xhr.responseText;
}
}
})
</script>
1.2、设置请求头信息
页面内容:
//设置请求头内容的类型
xhr.setRequestHeader('Content-Type','application/x-www-from-urlencoded');
//设置自定义请求头内容
xhr.setRequestHeader('name','hxxy');
服务端设置:
app.all('/server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应头, 设置允许自定义头信息
response.setHeader('Access-Control-Allow-Headers','*');
//响应内容
response.send('hello express All');
});
1.3json格式数据
服务端:
//设置返回json的服务端路由规则
app.all('/json-server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应头, 设置允许自定义头信息
response.setHeader('Access-Control-Allow-Headers','*');
const data={
name:'hxxy'
}
//转化为String类型-----响应内容只能是String或者buffer
let str=JSON.stringify(data);
//响应内容
response.send(str);
});
页面:
<body>
<div id="res"></div>
</body>
<script>
window.onkeydown=function(){
//创建对象
let xhr=new XMLHttpRequest();
//设置返回类型
xhr.responseType='json';
//添加参数
xhr.open('GET','http://localhost:8000/json-server');
//发送
xhr.send();
//处理响应
xhr.onreadystatechange=function(){
if (xhr.readyState===4 && (xhr.status>=200 && xhr.status<300)) {
res.innerHTML=xhr.response.name ;
}
}
}
</script>
1.4 IE缓存问题
原因:IE浏览器对于Ajax请求会存在缓存,请求值发送一次。
解决方法:浏览器缓存根据url来记录,修改动态url地址即可。
xhr.open("get","/testAJAX?t="+Date.now());
1.5 请求超时与网络延迟问题
服务端模拟超时:
//设置延迟
app.get('/delay',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
setTimeout(()=>{
response.send('delay');
},2000)
});
页面部分接收:
//超时异常回调
xhr.ontimeout=function(){
alert('网络异常')
}
//网络异常回调
xhr.onerror=function(){
alert('请稍后重试')
}
请求手动取消
xhr.abort()
1.6 API使用小结
XMLHttpRequest():创建 XHR 对象的构造函数
open():初始化一个请求,参数为:(method, url[, async])
status:响应状态码值,如 200、404、405、500
statusText:响应状态文本,如 ‘ok’、’not found‘
readyState:标识请求状态的只读属性 0 1 2 3 4
onreadystatechange:绑定 readyState 改变的监听
responseType:指定响应数据类型,如果是 ‘json’,得到响应后自动解析响应
response:响应体数据,类型取决于 responseType 的指定
timeout:指定请求超时时间,默认为 0 代表没有限制
ontimeout:绑定超时的监听
onerror:绑定请求网络错误的监听
send(data):发送请求
abort():中断请求 (发出到返回之间)
getResponseHeader(name):获取指定名称的响应头值
getAllResponseHeaders():获取所有响应头组成的字符串
setRequestHeader(name, value):设置请求头
2、jquery发送Ajax请求
2.1简写方式
服务端准备
//设置jquery的请求地址
app.all('/jquert-server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应头, 设置允许自定义头信息
response.setHeader('Access-Control-Allow-Headers','*');
//响应内容为json
const data={
name:'jquery-json',
}
response.send(JSON.stringify(data));
});
页面部分
<body>
<button>get</button>
<button>post</button>
</body>
<script src="../../lib/jquery-1.7.2.js"></script>
<script type="text/javascript">
$('button').eq(0).click(function(){
$.get(
'http://localhost:8000/jquert-server',
{
s:100,
a:200,
},
function(data){
console.log(data);
},
'json'
)
})
$('button').eq(1).click(function(){
$.post(
'http://localhost:8000/jquert-server',
{
s:100,
a:200,
},
function(data){
console.log(data);
}
)
})
</script>
2.2通用方式
$('button').eq(2).click(function(){
$.ajax({
url:'http://localhost:8000/delay',
data:{
s:100,
a:200
},
type:'GET',
success:function(data){
console.log(data);
},
dataType:'json',
timeout:1500,
error:function(){
alert('出错了!!!');
}
})
})
2.3 Axsoi发送Ajax
bootcdn搜素axios引入标签
语法:
//get方式
axios.get(url,data)
//post方式
axios.post(url,data,config)
//通用方式
axios({
method,
url,
params,//url参数
headers,
data,
}).then(response=>{})
<body>
<button>get</button>
<button>post</button>
<button>ajax</button>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.0.0-alpha.1/axios.js"></script>
<script>
const btn=document.getElementsByTagName('button');
btn[0].onclick=function(){
axios.get(
'http://localhost:8000/axios-server',
{
params:{
conf_p1:200,
conf_p2:300
},
headers:{
conf_h1:200,
conf_h2:300,
},
data:{
conf_d1:200,
conf_d2:300,
}
}
)
}
btn[1].onclick=function(){
axios.post(
'http://localhost:8000/axios-server',
{
conf_p1:200,
conf_p2:300
},{
headers:{
conf_h1:200,
conf_h2:300,
},
data:{
conf_d1:200,
conf_d2:300,
}
}
)
}
btn[2].onclick=function(){
axios({
method:'post',
url:'http://localhost:8000/axios-server',
//url参数
params:{
ax_p1:200,
ax_p2:100,
},
headers:{
ax_h1:100,
ax_h2:200
},
data:{
ax_d1:100,
ax_d2:200
}
}).then(response=>{
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.data);
})
}
</script>
3、跨域
3.1同源策略
同源:协议、域名、端口号 必须完全相同。
违背同源策略就是跨域。
Ajax默认遵循同源策略。
3.2如何解决跨域
1)
JSONP是什么?
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明
才智开发出来,只支持get请求。
2) JSONP 怎么工作的?
在网页有一些标签天生具有跨域能力,比如: img link iframe script。
JSONP就是利用scdipt标签的跨域能力来发送请求的。
3)
JSONP的使用
3.2.1 script标签方法
(1)服务端
//jsonp测试
app.all('/jsonp',(request,response)=>{
const data={
name:'hxxy'
};
let str=JSON.stringify(data);
//注意以下拼接时用的是 ` 而不是 '单引号 便于拼接
response.end(`handel(${str})`);
})
(2)添加script标签,地址为服务端地址,解决跨域
<body>
<div id="res" style="width: 200px;height: 100px;border:solid 1px"></div>
</body>
<script>
function handel(data){
const res=document.getElementById('res');
res.innerHTML=data.name;
}
</script>
<script src="http://localhost:8000/jsonp"></script>
3.2.2 jquery发送jsonp请求
使用jQuery发送jsonp请求时,url后补上参数callback=?(固定写法)
//jquery-jsonp
app.all('/jquery-jsonp',(request,response)=>{
const data={
name:'hxxy',
time:'2022',
};
let str=JSON.stringify(data);
//注意以下拼接时用的是 ` 而不是 '单引号 便于拼接
//接收callback函数变量
let cb=request.query.callback;
response.end(`${cb}(${str})`);
})
网页界面取出数据
<body>
<div id="res" style="width: 200px;height: 100px;border:solid 1px"></div>
<button>点击获取</button>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script>
$('button').on('click',function(){
$.getJSON(
'http://localhost:8000/jquery-jsonp?callback=?',
function(data){
$('#res').html(`
${data.name}<br>
${data.time}
`)
}
)
})
</script>
3.3 CORS
1) CORS 是什么?
CORS (Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方
案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持
get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些
源站通过浏览器有权限访问哪些资源。
2) CORS怎么 工作的?
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应
以后就会对响应放行。
2)CORS使用
app.all('/server',(request,response)=>{
// 设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置响应头, 设置允许自定义头信息
response.setHeader('Access-Control-Allow-Headers','*');
//响应内容
response.send('hello express All');
});