Axios中的AJAX
AXIOS特性
使用CDN链接,在这里不用NPM安装
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>
国内用bootcdn更快
GET请求
const btn = document.querySelectorAll('button');
//配置base URL
axios.defaults.baseURL = 'http://127.0.0.1:8000';
btn[0].onclick = function(){
//GET请求
axios.get('/axiosServer',{
//url参数
params:{
id:114,
vip:007
},
//请求头信息
headers:{
name:'KUN.A.A',
age:'20'
}
}).then(value => {
console.log(value);
})
}
js后端
//axios发送
app.all('/axiosServer',(request,response)=>{
//设置相应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//可接受全部响应头
response.setHeader("Access-Control-Allow-Headers", "*");
const data = {name:'KUN.A.A'}
// response.send('Hello Jquery AJAX');
response.send(JSON.stringify(data));
})
后端返回值
可见后端返回值很多,比较完整,同时后端定义的KUN,A,A JSON对象也返回了
POST请求
与GET请求不同,格式稍微有点改变
HTML中的js
btn[1].onclick = function(){
//POST
axios.post('/axiosServer',
{//请求体
username:'admin',
password:'123456'
},{
//url参数
params:{
id:514,
vip:005
},
//请求头信息
headers:{
height:'1990cm',
weight:'500kg'
}
})
}
请求体在post函数中的第二个参数,其他参数对象在第三个参数
JS后端与GET相同,不再贴了
axios函数发送请求
个人觉得是最好的方式
btn[2].onclick = function(){
axios({
//请求方法
method : 'POST',
//url
url:'/axiosServer',
//url参数
params:{
vip:1919,
level:810
},
//头信息
headers:{
h:150,
w:120
},
//请求体餐数
data:{
username:'KUN.A.A',
password:'1145141919810'
}
}).then(Response => {
//以下代码获取响应体中内容
//可根据具体要求修改
console.log(Response);
//响应状态码
console.log(Response.status);
//响应状态字符串
console.log(Response.statusText);
//响应头信息
console.log(Response.headers);
//响应体
console.log(Response.data);
})
}
完全是一种key - value的形式,只需要按照AXIOS的规则,都可以通过查询官方文档解决
同时JS后端也不变
CONSOL.LOG打印的一串
fetch函数发送AJAX请求
这个函数属于全局函数,可以直接调用
结果是promise对象
改一下后端名字以做区分
//fetch服务
app.all('/fetchServer',(request,response)=>{
//设置相应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//可接受全部响应头
response.setHeader("Access-Control-Allow-Headers", "*");
const data = {name:'KUN.A.A'}
// response.send('Hello Jquery AJAX');
response.send(JSON.stringify(data));
})
前端HTML
<script>
const btn = document.querySelector('button');
btn.onclick = function(){
fetch('http://127.0.0.1:8000/fetchServer?id=10',{
//请求方法
method:'POST',
//请求头
headers:{
name:'KUN.B.B',
},
//请求体
body:'username=admin&password=admin'
}).then(response => {
// console.log(response);
// return response.text();
return response.json();
}).then(response => {
console.log(response);
})
}
</script>
不同的是需要做两次promise,第一次用对象的函数,第二次才能取到后端返回的值
同时可以直接在URL中写参数
图就不贴了,和前面大同小异
同源策略
浏览器的安全机制
AJAX默认支持同源策略
违背同源策略就是跨域
跨域问题很常见
不是同源策略需要做适配
简单例子,这次端口改成9000,同时也可以复习NODE.JS原生下AJAX请求与回调
完整前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
</head>
<body>
<h1>H1H1H1</h1>
<button>点击获取用户数据</button>
<script>
const btn = document.querySelector('button');
btn.onclick = function(){
const x = new XMLHttpRequest();
//因为满足同源策略,URL可以简写
x.open("GET",'/data');
//发送
x.send();
x.onreadystatechange = function(){
if(x.readyState === 4){
if(x.status >= 200 && x.status < 300){
console.log(x.response);
}
}
}
}
</script>
</body>
</html>
JS后端
const { request, response } = require('express');
const express = require('express');
const app = express();
app.get('/home',(request,response) => {
//响应一个页面
response.sendFile(__dirname + '/index.html');
});
app.get('/data',(request,response) => {
response.send('用户数据')
})
app.listen(9000,() => {
console.log("9000端口已启动");
})
比较简单就不贴图了
这个部分简单介绍了什么是同源并举例,前面的代码大部分是同源只不过学习了不同方法发送AJAX请求与AJAX需要注意的点。
AJAX跨域解决
非官方跨域解决方案
JSONP
只支持GET请求
原生HTML一些标签本来就支持跨域
JSONP就是利用script的跨域能力来发送请求
即是script请求发过去之后,JS后端发回的是JS代码,否则浏览器引擎无法解析
新建一个非同源文件,即跨域,不在同一文件夹下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>跨域原理</title>
<style>
#result{
width: 400px;
height: 150px;
border: solid 1px rgb(255, 0, 0);
}
</style>
</head>
<body>
<div id="result"></div>
<script>
//处理数据,自定义函数
function handle(data){
//获取result元素
const result = document.getElementById('result');
result.innerHTML = data.name;
}
</script>
<script src="http://127.0.0.1:8000/jsonpServer"></script>
</body>
</html>
注意处理数据时候自定义了函数handle
JS后端 继续在8000端口的server中添加
//jsonp服务
app.all('/jsonpServer',(request,response)=>{
// response.send('consol.log(hello jsonpServer)');
const data = {
name:'KUN.C.C'
};
//将数据转换为字符串
let str = JSON.stringify(data);
//返回结果,返回自定义函数并传参
response.end(`handle(${str})`);
})
注意end中是键盘左上的``而不是’’
原生JSONP实现
具体做法在代码中比较清楚
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSONP案列</title>
</head>
<body>
用户名:<input type="text" id = "username">
<p></p>
<script>
//获取input元素
const input =document.querySelector('input');
const p = document.querySelector('p');
//声明handle函数
function handle(data){
input.style.border = "solid 1px #f00";
//修改P标签提示文本
p.innerHTML = data.msg;
}
//绑定事件
input.onblur = function(){
//获取用户的输入值
let username = this.value;
//向服务端发送请求检测用户名是否存在
//1.创建script标签
const script = document.createElement('script');
//2.设置标签src属性
script.src = 'http://127.0.0.1:8000/check-username';
//3.将script插入到文档中
document.body.appendChild(script);
}
</script>
</body>
</html>
JS服务端
//原生JSONP案列
app.all('/check-username',(request,response)=>{
// response.send('consol.log(hello jsonpServer)');
const data = {
exist:1,
msg:'用户名已存在'
};
//将数据转换为字符串
let str = JSON.stringify(data);
//返回结果,返回自定义函数并传参
response.end(`handle(${str})`);
})
Jquery发送JSONP请求
用Jquery发送JSONP的话非常方便
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Jquery发送JSONP AJAX请求</title>
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<style>
#result{
width: 450px;
height: 180px;
border: solid 1px #f00;
}
</style>
</head>
<body>
<button>点击发送jsonp请求</button>
<div id = "result">
</div>
<script>
$('button').eq(0).click(function(){
$.getJSON('http://127.0.0.1:8000/Jquery-jsonp-server?callback=?',function(data){
// console.log(data);
$('#result').html(`
名称:${data.name}<br>
小区:${data.city}
`)
})
})
</script>
</body>
</html>
注意Jquery发送JSONP请求时需要加?callback=?参数,以方便服务端回调并显示
JS
//Jquery发送JSONP的AJAX请求
app.all('/Jquery-jsonp-server',(request,response)=>{
// response.send('consol.log(hello jsonpServer)');
const data = {
name:'KUN.A.A',
city:['北京','上海','武汉']
};
//将数据转换为字符串
let str = JSON.stringify(data);
//接收callback参数
let cb = request.query.callback;
//返回结果,返回自定义函数并传参
response.end(`${cb}(${str})`);
})
JS服务端需要接收callback参数,并传参,用EI表达式把cb传回,前端
这就是Jquery用JSONP解决跨域问题的方法
设置CORS解决跨域问题的方案
这是解决AJAX跨域另一个方案,并且是官方的跨域解决方案,正规
CORS,跨域资源共享,不需要对客户端做任何操作,完全在服务器中处理,支持GET与POST,跨域通过服务端解决,新增了一组HTTP首部字段
具体首部字段可以看官方文档,同时前面的很多知识点和扩展的官方文档也很完备
最重要的是设置前面一些代码中有的响应头,即可完成跨域请求
//设置响应头
response.setHeader("Access-Control-Allow-Origin",'*')
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CORS官方跨域请求</title>
<style>
#result{
width: 350px;
height: 180px;
border: solid 1px #f00;
}
</style>
</head>
<body>
<button>发送请求</button>
<div id="result"></div>
<script>
const btn = document.querySelector('button');
btn.onclick = function(){
//1.创建对象
const x = new XMLHttpRequest();
//2.初始化
x.open("GET","http://127.0.0.1:8000/corsServer");
//3.发送
x.send();
//4.绑定事件
x.onreadystatechange = function(){
if(x.readyState === 4){
if(x.status >= 200 && x.status < 300){
// console.log(x.response);
result.innerHTML = x.response;
}
}
}
}
</script>
</body>
</html>
//CORS原生AJAX跨域请求
app.all('/corsServer',(request,response) => {
//设置响应头
response.setHeader("Access-Control-Allow-Origin",'*')
response.send('hello CORS');
})