AJAX学习笔记
第一章: 原生Ajax
1.1Ajax简介
- Ajax全称为Asynchronous Javascript And XML,即异步JS和XML
- 通过Ajax可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据
- AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式
1.2 XML简介
- XML:可扩展标记语言
- XML:被设计用来传输和存储数据
- XML和HTML类似,不同点:HTML中都是预定义标签,XML中没有预定义标签,全是自定义标签,用 来表示一些数据
- 现在已被JSON取代
比如:我又一个学生数据:
name="孙悟空";age=18;gender="男";
用XML表示:
<student>
<name>孙悟空</name>
</student>
1.3 AJAX 的特点
1.3.1 AJAX的优点
- 可以无刷新页面与服务端进行通信
- 允许你根据用户事件来更新部分页面内容
1.3.2 AJAX 的缺点
- 没有浏览历史,不能回退
- 存在跨域问题(同源)
- SEO不友好(爬虫获取不到信息)
1.4 Node.js安装
1.5 Express安装
npm init --yes
npm i express
然后同级目录下创建 js文件
//1.引入express
const express=require('express');
//2.创建应用对象
const app=express();
//3.创建路由规则
//request是对请求报文的封装
//response 是对响应报文的封装
app.get('/server',(request,response)=>{ //针对get
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
response.send('Hello World');
})
app.post('/server',(request,response)=>{ //针对post
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
response.send('Hello World');
})
//4.监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中...")
})
启动:node xxx.js
第二章 原生AJAX的使用
2.1get请求
2.1.2使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AJAX GET请求</title>
<style>
#result {
width: 100px;
height: 100px;
border: solid 1px red;
}
</style>
<script src="../jquery.min.js"></script>
</head>
<body>
<button>点击发送请求</button>
<div id="result"></div>
<script>
$('button').on('click', function () {
// console.log("fgg")
//1.创建对象
var xhr = new XMLHttpRequest();
//2.初始化 设置请求方法和url
xhr.open('GET', 'http://localhost:8000/server');
//3.发送
xhr.send();
//4.事件绑定,处理服务端返回的结果
/**
* on when 当...时候
* readystate 是xhr对象中的属性, 表示状态0(初始化) 1(open完毕) 2(send完毕) 3(返回部分结果) 4(返回所有结果)
*/
xhr.onreadystatechange = function () {
//共改变4次,触发4次
//判断(服务端返回了所有的结果)
if (this.readyState === 4) {
//判断响应状态码 200 404 403 401 500
//2xx成功
if (this.status >= 200 && this.status < 300) {
//处理结果 行 头 空行 体
// console.log(this.status);//状态码 200
// console.log(this.statusText);//状态码字符串 OK
// console.log(this.getAllResponseHeaders());//所有响应头
// console.log(this.response);//响应体
$('#result').html(this.response);
}
}
}
});
</script>
</body>
</html>
2.1.2 get请求加参数
xhr.open('GET', 'http://localhost:8000/server?username=chenyanjie&age=3');
2.2 POST请求
2.2.1 使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AJAX POST请求</title>
<style>
#result {
width: 100px;
height: 100px;
border: solid 1px red;
}
</style>
<script src="../jquery.min.js"></script>
</head>
<body>
<!--<button>点击发送请求</button>-->
<div id="result"></div>
<script>
$('div').on({
'mouseover': function () {
// console.log("fgg")
//1.创建对象
var xhr = new XMLHttpRequest();
//2.初始化 设置请求方法和url
xhr.open('POST', 'http://localhost:8000/server?username=小红&age=13');
//3.发送
xhr.send();
//4.事件绑定,处理服务端返回的结果
/**
* on when 当...时候
* readystate 是xhr对象中的属性, 表示状态0(初始化) 1(open完毕) 2(send完毕) 3(返回部分结果) 4(返回所有结果)
*/
xhr.onreadystatechange = function () {
//共改变4次,触发4次
//判断(服务端返回了所有的结果)
if (this.readyState === 4) {
//判断响应状态码 200 404 403 401 500
//2xx成功
if (this.status >= 200 && this.status < 300) {
//处理结果 行 头 空行 体
// console.log(this.status);//状态码 200
// console.log(this.statusText);//状态码字符串 OK
// console.log(this.getAllResponseHeaders());//所有响应头
// console.log(this.response);//响应体
$('#result').html(this.response);
}
}
}
},
'mouseout': function () {
$('#result').html('');
}
}
);
</script>
</body>
</html>
2.2.2 post请求加参数
xhr.send(‘username=小红&age=3’);
2.3设置请求头信息
发送之前设置请求头:
xhr.setRequestHeader(‘Content-Type’,‘application/x-www-form-urlencoded’);
//3.发送
xhr.send(‘username=小红&age=3’);
注意:非预定义请求头会报错,如:
xhr.setRequestHeader(‘aaa’,‘ddd’);//非预定义请求头会报错
此时需要在后端返回中加入
app.post(‘/server’,(request,response)=>{ //针对post
//设置响应头 设置允许跨域
response.setHeader(‘Access-Control-Allow-Origin’,‘‘);
//设置响应头,设置接收所有请求头
response.setHeader(‘Access-Control-Allow-Headers’,’’);
//设置响应体
response.send(‘Hello World’);
})
此时还会报错,因为之前会发送一个OPTIONS请求,这个OPTINONS并没有获得校验的结果
添加请求方式:
app.options(‘/server’,(request,response)=>{ //针对post
//设置响应头 设置允许跨域
response.setHeader(‘Access-Control-Allow-Origin’,‘‘);
//设置响应头,设置接收所有请求头
response.setHeader(‘Access-Control-Allow-Headers’,’’);
//设置响应体
response.send(‘Hello World’);
})
也可以只用将app.post, 和app.options等替换为 app.all,可以接收任何请求
2.4 返回结果JSON数据处理
Express改造响应结果:
app.all('/json-server',(request,response)=>{ //针对post
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应头,设置接收所有请求头
response.setHeader('Access-Control-Allow-Headers','*');
//设置响应体
var data={
name:"小红",
age:12
}
//将对象转化为json字符串
var jsonString = JSON.stringify(data);
response.send(jsonString);
})
2.4.1 前端手动处理处理数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AJAX POST请求</title>
<style>
#result {
width: 100px;
height: 100px;
border: solid 1px red;
}
</style>
<script src="../jquery.min.js"></script>
</head>
<body>
<!--<button>点击发送请求</button>-->
<div id="result"></div>
<script>
$('div').on({
'mouseover': function () {
// console.log("fgg")
//1.创建对象
var xhr = new XMLHttpRequest();
//2.初始化 设置请求方法和url
xhr.open('GET', 'http://127.0.0.1:8000/json-server');
// xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// xhr.setRequestHeader('aaa','ddd');//非预定义请求头会报错
//3.发送
xhr.send();
//4.事件绑定,处理服务端返回的结果
/**
* on when 当...时候
* readystate 是xhr对象中的属性, 表示状态0(初始化) 1(open完毕) 2(send完毕) 3(返回部分结果) 4(返回所有结果)
*/
xhr.onreadystatechange = function () {
//共改变4次,触发4次
//判断(服务端返回了所有的结果)
if (this.readyState === 4) {
//判断响应状态码 200 404 403 401 500
//2xx成功
if (this.status >= 200 && this.status < 300) {
//手动转换数据
var parse = JSON.parse(this.response); // this.response就是json字符串
console.log(parse);//{name: '小红', age: 12}
$('#result').html(parse.name);//小红
}
}
}
},
'mouseout': function () {
$('#result').html('');
}
}
);
var data={
name:"小红",
age:12
}
// console.log(data.toString());
console.log(JSON.stringify(data));
</script>
</body>
</html>
2.4.1 前端自动处理处理数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AJAX POST请求</title>
<style>
#result {
width: 100px;
height: 100px;
border: solid 1px red;
}
</style>
<script src="../jquery.min.js"></script>
</head>
<body>
<!--<button>点击发送请求</button>-->
<div id="result"></div>
<script>
$('div').on({
'mouseover': function () {
// console.log("fgg")
//1.创建对象
var xhr = new XMLHttpRequest();
//2.初始化 设置请求方法和url
xhr.open('GET', 'http://127.0.0.1:8000/json-server');
//设置响应体数据类型
xhr.responseType="json";
// xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// xhr.setRequestHeader('aaa','ddd');//非预定义请求头会报错
//3.发送
xhr.send();
//4.事件绑定,处理服务端返回的结果
/**
* on when 当...时候
* readystate 是xhr对象中的属性, 表示状态0(初始化) 1(open完毕) 2(send完毕) 3(返回部分结果) 4(返回所有结果)
*/
xhr.onreadystatechange = function () {
//共改变4次,触发4次
//判断(服务端返回了所有的结果)
if (this.readyState === 4) {
//判断响应状态码 200 404 403 401 500
//2xx成功
if (this.status >= 200 && this.status < 300) {
//手动转换数据
// var parse = JSON.parse(this.response); // this.response就是json字符串
// console.log(parse);//{name: '小红', age: 12}
// $('#result').html(parse.name);//小红
var parse = this.response;//{name: '小红', age: 12} this.response就是json对象,
$('#result').html(parse.name);//小红
}
}
}
},
'mouseout': function () {
$('#result').html('');
}
}
);
var data={
name:"小红",
age:12
}
// console.log(data.toString());
console.log(JSON.stringify(data));
</script>
</body>
</html>
2.5 nodemon --自动热部署重启express后端服务
全局安装: npm i -g nodemon
使用nodemon运行服务: nodemon xxx.js
2.6 IE缓存问题
由于IE浏览器存在缓存问题,同一个请求的结果会进行缓存,再次请求时会取到上次的数据,可以将2次相同的请求变为不同的请求.
xhr.open('GET', 'http://127.0.0.1:8000/ie?t='+Date.now());
2.7AJAX超时与网络异常
客户端代码
//超时设置2s
xhr.timeout=2000; //2秒内没有返回结果,报错.
//超时回调
xhr.ontimeout=function(){
alert('网络异常,请稍后重试');
}
//网络异常回调
xhr.onerror=function(){
alert('你的网络似乎出现了一些问题!')
}
服务端代码:设置3s的延迟
setTimeout(()=>{
// 延迟响应
response.send("hello 4diee");
},3000);
2.8 取消请求
xhr.abort();
客户端代码
var xhr=null;
$('#send').on('click', function () {
//1.创建对象
xhr = new XMLHttpRequest();
//超时设置2s
xhr.timeout=2000;
//超时回调
xhr.ontimeout=function(){
alert('网络异常,请稍后重试');
}
//网络异常回调
xhr.onerror=function(){
alert('你的网络似乎出现了一些问题!')
}
//2.初始化 设置请求方法和url
xhr.open('GET', 'http://127.0.0.1:8000/server');
//3.发送
xhr.send();
xhr.onreadystatechange = function () {
//共改变4次,触发4次
//判断(服务端返回了所有的结果)
if (this.readyState === 4) {
//判断响应状态码 200 404 403 401 500
//2xx成功
if (this.status >= 200 && this.status < 300) {
$('#result').html(this.response);
}
}
}
}
);
$('#cancel').on('click', function () {
xhr.abort();
});
服务端代码:
app.all('/server',(request,response)=>{ //针对get
//设置响应头 设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
// response.send('Hello World');
setTimeout(()=>{
// 延迟响应
response.send("hello 4diee");
},3000);
})
2.9 重复请求问题
加一个标志位,如果正在请求,则取消请求,进行发送.
var xhr=null;
//标识变量
var isSending = false;//是否正在发送AJAX请求
$('#send').on('click', function () {
if(isSending) xhr.abort();
//1.创建对象
xhr = new XMLHttpRequest();
isSending=true;
//2.初始化 设置请求方法和url
xhr.open('GET', 'http://127.0.0.1:8000/server');
//3.发送
xhr.send();
xhr.onreadystatechange = function () {
//共改变4次,触发4次
//判断(服务端返回了所有的结果)
if (this.readyState === 4) {
isSending=true;//请求结束时
//判断响应状态码 200 404 403 401 500
//2xx成功
if (this.status >= 200 && this.status < 300) {
$('#result').html(this.response);
}
}
}
}
);
第三章 jQuery使用AJAX
3.1get请求
$.get(url,[data],[callback],[type])
- url:请求的URL地址
- data:请求携带的参数
- callback:载入成功时回调函数
- type:设置返回内容格式,xml,html,script,json,text,_default.(默认地,jQuery 会智能判断。)
$('#get').on('click', function () {
var url="http://127.0.0.1:8000/server3";
var data={a:100,b:200};
var type='json';
$.get(url, data, function (data) {
console.log(data);
});
});
3.2 post请求
$.post(url,[data],[callback],[type])
- url:请求的URL地址
- data:请求携带的参数
- callback:载入成功时回调函数
- type:设置返回内容格式,xml,html,script,json,text,_default…
$('#post').on('click', function () {
var url="http://127.0.0.1:8000/server3";
var data={a:100,b:200};
var type='';
$.get(url,data,function (data) {
console.log(data);
});
});
3.3 通用型请求
$.ajax({
url: "http://127.0.0.1:8000/server3",
data: {a: 100, b: 200},
type: 'GET',
//响应体结果
dataType: 'json',
//成功的回调函数
success: function (data) {
console.log(data);
},
//超时时间
timeout: 2000,
// 失败回调函数
error: function () {
console.log('调用出错了');
},
//头信息
headers:{
c:300,
d:400
}
}
)
第四章 其他
4.1Axios (Ajax工具包)
4.1.1 使用:
<script src="https://cdn.jsdelivr.net/npm/axios@1.1.2/dist/axios.min.js"></script>
4.1.2 get请求
//get请求
axios.get('http://127.0.0.1:8000/server3',
//url参数
{
params: {
id: 100,
name: 'dog'
},
//请求头信息
headers: {
name: 'ff',
age: 30
}
}
).then(value => {
console.log(value.data);//结果
})
应用axios.defaults.baseURL属性:
axios.defaults.baseURL='http://127.0.0.1:8000'
//get请求
axios.get('/server3',
//url参数
{
params: {
id: 100,
name: 'dog'
},
//请求头信息
headers: {
name: 'ff',
age: 30
}
}
).then(value => {
console.log(value.data);//结果
})
4.1.3 post请求
axios.defaults.baseURL = 'http://127.0.0.1:8000'
//post请求
axios.post('/server3',
//请求体
{
username: '小白',
password: 33
},
{
//url参数
params: {
id: 100,
name: 'dog'
},
//请求头信息
headers: {
name: 'ff',
age: 30
}
}
).then(value => {
console.log(value.data);//结果
})
4.1.4 通用方式发送请求
axios({
//url
url: '/server3',
//url参数
params: {
vip: 10,
level: 30
},
//头信息
headers: {
a: 100,
b: 30
},
//请求体参数
data: {
username: 'admin',
password: 'admin'
},
method:'POST'
}).then(value => {
console.log(value.data);
})
4.2 Fetch函数发送AJAX请求
fetch('http://127.0.0.1:8000/server3',{
//请求方法
method: 'POST',
//请求头
headers:{
name:'xiaohong'
},
//请求体
body: 'username=xiaobai&password=admin'
}).then(response=>{
// return response.text();//如果结果是字符串
return response.json();//如果结果是JSON
}).then(response=>{
console.log(response);
})
第五章 跨域
5.1 同源策略
同源策略(Same-Origin Policy)最早由Netspace公司提出,是浏览器的一种安全策略.
- 同源:协议、域名、端口号 必须完全相同。
- 违背同源策略就是跨域
- Ajax默认时遵循同源策略的
var xhr = new XMLHttpRequest();
xhr.open('GET', '/data');//同源可以使用简写
xhr.send();
xhr.onreadystatechange = function () {
//共改变4次,触发4次
//判断(服务端返回了所有的结果)
if (this.readyState === 4) {
//判断响应状态码 200 404 403 401 500
//2xx成功
if (this.status >= 200 && this.status < 300) {
console.log(this.response);
}
}
}
5.2 如何解决跨域
5.2.1 JSONP
- JSONP是什么?
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求。 - JSONP怎么工作的?
在网页有一些标签天生具有跨域能力,比如:img link iframe script.
JSONP就是利用script标签的跨域能力来发送请求的。 - JSONP的使用
3.1 动态的创建一个script标签
3.2 设置script的src,设置回调函数。
注意:关闭这个选项,不然跨域是idea会提示信息
5.2.1.1 原生实现JSONP
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原生JSONP实现</title>
<script src="../../jquery.min.js"></script>
</head>
<body>
用户名:<input type="text" id="username">
<!--<script src="http://localhost:63342/MyCode/AJAX/Express/myCode/05-%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5/orgin.js"></script>-->
<script>
var handle = function (data) {
// console.log(data);
};
$('#username').on('blur', function () {
var val = this.value;
console.log(val);
var script = document.createElement('script');
script.src= 'http://127.0.0.1:8000/jsonp-server';
$('body').append(script);
});
</script>
</body>
</html>
app.all('/jsonp-server',(request,response)=>{ //针对get
data={
name:'小红',
age:19
}
var str = JSON.stringify(data);
response.end('handle('+str+')');//需要返回js代码才可以解析
})
5.2.1.2 jQuery实现JSONP
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>原生JSONP实现</title>
<script src="../../jquery.min.js"></script>
</head>
<body>
<!--用户名:<input type="text" id="username">-->
用户名:<input type="text" id="username">
<script>
var handle = function (data) {
console.log(data);
};
$('#username').on('blur', function () {
$.getJSON('http://127.0.0.1:8000/jsonp-server?callback=?', function (data) {
console.log(data);
});//callback=?固定写法, ?代表这个回调函数
});
</script>
</body>
</html>
app.all('/jsonp-server',(request,response)=>{ //针对get
data={
name:'小红',
age:19
}
var str = JSON.stringify(data);
//接受callback参数
var callback = request.query.callback;
response.end(`${callback}(${str})`);//需要返回js代码才可以解析
})
5.2.2 CORS
参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
- CORS是什么?
CORS(Cross–Origin Resource Sharing),跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户瑞做任何特殊的操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访间哪些资源
- CORS怎么工作的?
COS是通过设置一·个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。
response.setHeader('Access-Control-Allow-Origin','*');//对所有源都允许
response.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:5000');//对源http://127.0.0.1:5000的才可以
//其他跨域等等,可以复制下面nginx下面的内容.
- nginx解决跨域问题
server {
listen 80; # 监听的端⼝
server_name localhost; # 域名或ip
location / { # 访问路径配置
#允许跨域请求的域,* 代表所有
add_header 'Access-Control-Allow-Origin' *;//add_header添加响应头,这些配置可以放在server下,对所有location生效
#允许带上cookie请求
add_header 'Access-Control-Allow-Credentials' 'true';
#允许请求的方法,比如 GET/POST/PUT/DELETE
add_header 'Access-Control-Allow-Methods' *;
#允许请求的header
add_header 'Access-Control-Allow-Headers' *;
root /usr/share/nginx/html;# 根⽬录
index index.html index.htm; # 默认⾸⻚
}
error_page 500 502 503 504 /50x.html; # 错误⻚⾯
location = /50x.html {
root html;
}