文章目录
第一章 原生AJAX
1.1 AJAX简介
AJAX全称为Asynchronous Javascript And XML,就是异步的JS和XML。
通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势==:页面无刷新获取数据==。
AJAX不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
1.2 XML简介
XML可扩展标记语言。
XML 被设计用来传输和存储数据。
XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据。
<!-- 例如:用XML表示一个学生数据:-->
<student>
<name>孙悟空</name>
<age>18</age>
<gender>男</gender>
<lstudent>
现在已经被JSON取代了。
// 用JSON表示:
{"name"∵"孙悟空", "age":18,"gender":"男"}
1.3 ajax的特点
1.3.1 AJAX的优点
- 可以无需刷新页面而与服务器端进行通信。
- 允许你根据用户事件来更新部分页面内容。
1.3.2 AJAX的缺点
- 没有浏览历史,不能回退;
- 存在跨域问题;
- SEO不友好;
1.4 AJAX的使用
1.4.1核心对象
- XMLHttpRequest,AJAX的所有操作都是通过该对象进行的。
1.4.2使用步骤
-
1.创建XMLHttpRequest实例对象
const xhr = new XMLHttpRequest()
-
2.设置请求信息
xhr.open(method,url)//配置请求 xhr.setRequestHeader(key,value)//设置请求头(可选)
-
3.发送请求
xhr.send(body) //get请求不传 body参数,只有post 请求使用
-
4.接收响应
xhr.onreadystatechange = ()=>{ if(xhr.readyState === 4 && xhr.status >= 200 && xhr.status<300 ){ console.log(xhr.response) } }
1.4.3 解决ie缓存问题
-
问题:
- 在一些浏览器中(IE),由于缓存机制的存在,ajax只会发送的第一次请求,剩余多次请求不会在发送给浏览器而是直接加载缓存中的数据。
- 在chrome中,会有协商缓存的过程,当前面发送过的请求后,后面再发送请求给服务器,服务器返回告诉浏览器响应结果未改变,浏览器自己使用前面的缓存结果。但是ie这个浏览器问都不问浏览器,发现url一样,就直接强制使用缓存了,所以ie须解决这个问题
-
解决方式:
- 浏览器的ajax缓存是根据url地址来记录的,所以我们只需要修改url
地址即可避免缓存问题xhr.open( 'get' , 'url?t='+Date.now()) // 不能用模板字符串, 因为本来就是问了解决ie浏览器缓存问题,ie不支持模板字符串
- 浏览器的ajax缓存是根据url地址来记录的,所以我们只需要修改url
1.4.4 AJAX请求状态
xhr.readyState 可以用来查看请求当前的状态
- 0: 表示 XMLHttpRequest实例已经生成,但open未调用。
- 1: open 已调用,但send还未调用,此时仍然可以修改请求头信息。
- 2: 表示send()方法已经执行,并且头信息和状态码已经收到。
- 3: 表示正在接收服务器传来的部分数据。
- 4: 表示数据已经接收完毕
第2章:jQuery中的AJAX
2.1 get请求
$.get(url, [data], [callback], [type])
- url:请求的URL地址。
- data:请求携带的参数。
- callback:载入成功时回调函数。
- type:设置返回内容格式,xml, html, script, json, text,_default。
2.2 post请求
$.post(url,[data], [callback], [type])
- url:请求的URL地址。
- data:请求携带的参数。
- callback:载入成功时回调函数。
- type:设置返回内容格式,xml, html, script, json, text,_default。
第3章:跨域
3.1同源策略
-
同源策略(Same-Origin Policy)由Netscape 公司提出,是浏览器的一种安全策略。
-
同源的规则:协议、域名、端口号必须完全相同。‘
-
违背同源策略又称:跨域。
-
非同源受到哪些限制?
- cookie不能读取
- DOM无法获得
- Ajax请求不能获取数据
案例
1_ajax小试牛刀.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>1_ajax小试牛刀</title>
<style>
#content{
width: 300px;
height: 100px;
border: 1px solid black;
margin-top: 10px;
}
</style>
</head>
<body>
<h3>该页面是测试:ajax小试牛刀</h3>
<button id="btn">点我发送请求(原生js-ajax-get)</button>
<div id="content"></div>
<script type="text/javascript" >
//获取按钮
const btn = document.getElementById('btn')
const content = document.getElementById('content')
//给按钮绑定监听
btn.onclick = ()=>{
//1.创建xhr实例对象
const xhr = new XMLHttpRequest()
//on 当xxx时候
//ready 准备
//state 状态
//change 状态
//xhr内部有5种状态,值分别为:0、1、2、3、4
//xhr实例对象,在实例出来的那一刻状态就是0
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4){
console.log(xhr.response);
content.innerHTML = `<h3>${xhr.response}</h3>`
}
}
//2.指定发送请求的:method、url
xhr.open('GET','http://127.0.0.1:8080/test_get')
//3.发送请求
xhr.send()
}
</script>
</body>
</html>
2_xhr的5种状态.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>2_xhr的5种状态</title>
<style>
#content{
width: 300px;
height: 100px;
border: 1px solid black;
margin-top: 10px;
}
</style>
</head>
<body>
<h3>该页面是测试:xhr的5种状态</h3>
<button id="btn">点我发送请求(原生js-ajax-get)</button>
<div id="content"></div>
<script type="text/javascript" >
//获取按钮
const btn = document.getElementById('btn')
const content = document.getElementById('content')
//给按钮绑定监听
btn.onclick = ()=>{
//1.创建xhr实例对象
const xhr = new XMLHttpRequest()
//xhr实例对象,在实例出来的那一刻状态就是0
/*
xhr内部有5种状态,值分别为:0、1、2、3、4
0:实例出来的那一刻状态就是0,初始状态。
1:open已经调用了,但是send还没有调用,此时可以修改请求头内容。
2:send已经调用了,已经无法修改请求头
3:已经回来一部分数据了,小的数据会在此阶段一次性接收完毕,较大的数据有待进一步接收,响应头回来了。
4:数据全部接收完毕
*/
xhr.onreadystatechange = ()=>{
/* if(xhr.readyState === 1){
xhr.setRequestHeader('demo',123) //配置请求头
} */
/* if(xhr.readyState === 2){
xhr.setRequestHeader('demo',123) //配置请求头--报错
} */
if(xhr.readyState === 3){
console.log('3时接收到的数据',xhr.response);
console.log('3时接收到的响应头',xhr.getAllResponseHeaders());
}
if(xhr.readyState === 4 && (xhr.status >= 200 && xhr.status < 300)){
console.log(xhr.response);
content.innerHTML = `<h3>${xhr.response}</h3>`
}
}
//2.指定发送请求的:method、url
xhr.open('GET','http://127.0.0.1:8080/test_get')
//3.发送请求
xhr.send()
}
</script>
</body>
</html>
3_ajax_get请求.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>3_ajax_get请求</title>
<style>
#content{
width: 300px;
height: 100px;
border: 1px solid black;
margin-top: 10px;
}
</style>
</head>
<body>
<h3>该页面是测试:ajax_get请求</h3>
<button id="btn">点我发送请求(原生js-ajax-get)</button>
<div id="content"></div>
<script type="text/javascript" >
//获取按钮
const btn = document.getElementById('btn')
const content = document.getElementById('content')
//给按钮绑定监听
btn.onclick = ()=>{
//1.创建xhr实例对象
const xhr = new XMLHttpRequest()
//绑定监听
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4 ){
if(xhr.status >= 200 && xhr.status < 300){
console.log(xhr.response);
content.innerHTML = `<h3>${xhr.response}</h3>`
}
}
}
//#region
/*
1.形如:key=value&key=value 就是query参数的urlencoded编码形式
2.形如:/xx/xxx/老刘/18 就是params参数
*/
//#endregion
//2.指定发送请求的:method、url、参数
// xhr.open('GET','http://127.0.0.1:8080/test_get?name=老刘&age=18') //携带query参数
xhr.open('PUT','http://127.0.0.1:8080/test_put') //携带params参数
//3.发送请求
xhr.send()
}
</script>
</body>
</html>
4_ajax_post请求.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>4_ajax_post请求</title>
<style>
#content{
width: 300px;
height: 100px;
border: 1px solid black;
margin-top: 10px;
}
</style>
</head>
<body>
<h3>该页面是测试:ajax_post请求</h3>
<button id="btn">点我发送请求(原生js-ajax-post)</button>
<div id="content"></div>
<script type="text/javascript" >
//获取按钮
const btn = document.getElementById('btn')
const content = document.getElementById('content')
//给按钮绑定监听
btn.onclick = ()=>{
//1.创建xhr实例对象
const xhr = new XMLHttpRequest()
//绑定监听
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4 ){
if(xhr.status >= 200 && xhr.status < 300){
console.log(xhr.response);
content.innerHTML = `<h3>${xhr.response}</h3>`
}
}
}
//2.指定发送请求的:method、url、参数
xhr.open('POST','http://127.0.0.1:8080/test_post')
//追加请求头用于标识携带请求体参数的编码形式--urlencoded
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')
//追加响应头用于标识携带请求体参数的编码形式--json
//xhr.setRequestHeader('Content-type','application/json')
//3.发送请求
const person = {name:'老刘',age:20}
xhr.send('name=老刘&age=18') //携带urlencoded编码形式的请求体参数
// xhr.send(JSON.stringify(person)) //携带json编码形式的请求体参数
}
</script>
</body>
</html>
5_ajax_解析json数据.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>5_ajax_解析json数据</title>
<style>
#content{
width: 300px;
height: 100px;
border: 1px solid black;
margin-top: 10px;
}
</style>
</head>
<body>
<h3>该页面是测试:ajax_解析json数据</h3>
<button id="btn">点我发送请求(原生js-ajax-get)</button>
<div id="content"></div>
<script type="text/javascript" >
const btn = document.getElementById('btn')
const content = document.getElementById('content')
btn.onclick = ()=>{
//实例xhr
const xhr = new XMLHttpRequest()
//绑定监听
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status <300){
const {name,age,sex} = xhr.response
content.innerHTML = (`
<ul>
<li>姓名:${name}</li>
<li>年龄:${age}</li>
<li>性别:${sex}</li>
<ul>
`)
}
}
}
//配置请求
xhr.open('GET','http://127.0.0.1:8080/get_person')
//responseType用于指定返回数据的格式
xhr.responseType = 'json'
//发送请求
xhr.send()
}
</script>
</body>
</html>
6_ajax_处理IE浏览器get请求缓存问题.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>6_ajax_处理IE-get请求缓存问题</title>
<style>
#content{
width: 300px;
height: 100px;
border: 1px solid black;
margin-top: 10px;
}
</style>
</head>
<body>
<h3>该页面是测试:ajax_处理IE-get请求缓存问题</h3>
<button id="btn">点我发送请求(原生js-ajax-get)</button>
<div id="content"></div>
<script type="text/javascript" >
const btn = document.getElementById('btn')
const content = document.getElementById('content')
btn.onclick = function(){
//实例xhr
const xhr = new XMLHttpRequest()
//绑定监听
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status <300){
console.log(xhr.response);
}
}
}
//配置请求
xhr.open('GET','http://127.0.0.1:8080/get_person?t='+Date.now())
//responseType用于指定返回数据的格式
xhr.responseType = 'json'
//发送请求
xhr.send()
}
</script>
</body>
</html>
7_ajax请求的异常与超时处理.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>7_ajax请求的异常与超时处理</title>
<style>
#content{
width: 300px;
height: 100px;
border: 1px solid black;
margin-top: 10px;
}
</style>
</head>
<body>
<h3>该页面是测试:ajax请求的异常与超时处理</h3>
<button id="btn">点我发送请求(原生js-ajax-get)</button>
<div id="content"></div>
<script type="text/javascript" >
const btn = document.getElementById('btn')
const content = document.getElementById('content')
btn.onclick = function(){
//实例xhr
const xhr = new XMLHttpRequest()
//绑定监听
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status <300){
const {name,age,sex} = xhr.response
content.innerHTML = (`
<ul>
<li>姓名:${name}</li>
<li>年龄:${age}</li>
<li>性别:${sex}</li>
<ul>
`)
}
}
}
//配置请求
xhr.open('GET','http://127.0.0.1:8080/get_person_delay')
//responseType用于指定返回数据的格式
xhr.responseType = 'json'
//配置出错的回调
xhr.onerror = ()=>{
alert('当前网络不稳定,请稍后重试');
}
//超时时间
xhr.timeout = 2000
//超时的回调
xhr.ontimeout = ()=>{
alert('网速不给力,请切换网络重试');
}
//发送请求
xhr.send()
}
</script>
</body>
</html>
8_ajax取消请求.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>8_ajax取消请求</title>
<style>
#content{
width: 300px;
height: 100px;
border: 1px solid black;
margin-top: 10px;
}
</style>
</head>
<body>
<h3>该页面是测试:ajax取消请求</h3>
<button id="btn">点我发送请求(原生js-ajax-get)</button>
<button id="btn2">取消请求</button>
<div id="content"></div>
<script type="text/javascript" >
const btn = document.getElementById('btn')
const btn2 = document.getElementById('btn2')
const content = document.getElementById('content')
let xhr
btn.onclick = ()=>{
//实例xhr
xhr = new XMLHttpRequest()
//绑定监听
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status <300){
const {name,age,sex} = xhr.response
content.innerHTML = (`
<ul>
<li>姓名:${name}</li>
<li>年龄:${age}</li>
<li>性别:${sex}</li>
<ul>
`)
}
}
}
//配置请求
xhr.open('GET','http://127.0.0.1:8080/get_person_delay')
//responseType用于指定返回数据的格式
xhr.responseType = 'json'
//配置出错的回调
xhr.onerror = ()=>{
alert('当前网络不稳定,请稍后重试');
}
//超时时间
xhr.timeout = 2000
//超时的回调
xhr.ontimeout = ()=>{
alert('网速不给力,请切换网络重试');
}
//发送请求
xhr.send()
}
btn2.onclick = ()=>{
xhr.abort()
}
</script>
</body>
</html>
9_避免多次重复请求.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>9_避免多次重复请求</title>
<style>
#content{
width: 300px;
height: 100px;
border: 1px solid black;
margin-top: 10px;
}
</style>
</head>
<body>
<h3>该页面是测试:避免多次重复请求</h3>
<button id="btn">点我发送请求(原生js-ajax-get)</button>
<div id="content"></div>
<script type="text/javascript" >
const btn = document.getElementById('btn')
const content = document.getElementById('content')
let xhr
let isLoading
btn.onclick = ()=>{
if(isLoading) xhr.abort()
//实例xhr
xhr = new XMLHttpRequest()
//绑定监听
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status <300){
isLoading = false
const {name,age,sex} = xhr.response
content.innerHTML = (`
<ul>
<li>姓名:${name}</li>
<li>年龄:${age}</li>
<li>性别:${sex}</li>
<ul>
`)
}
}
}
//配置请求
xhr.open('GET','http://127.0.0.1:8080/get_person_delay')
//responseType用于指定返回数据的格式
xhr.responseType = 'json'
//发送请求
xhr.send()
isLoading = true
}
</script>
</body>
</html>
10_jquery封装的ajax.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>10_jQuery封装的ajax</title>
<style>
#content{
width: 300px;
height: 100px;
border: 1px solid black;
margin-top: 10px;
}
</style>
<script type="text/javascript" src="./js/jquery.min.js"></script>
</head>
<body>
<h3>该页面是测试:jQuery封装的ajax</h3>
<button id="btn1">点我发送请求(jQuery-ajax-get)</button>
<button id="btn2">点我发送请求(jQuery-ajax-post)</button>
<div id="content"></div>
<script type="text/javascript" >
const btn1 = $('#btn1')
const btn2 = $('#btn2')
const content = $('#content')
btn1.click(()=>{
//使用jQuery发送ajax-get(完整版)
$.ajax({
url:'http://127.0.0.1:8080/test_jquery_get', //请求地址
method:'GET',//请求方式(默认值是GET)
data:{school:'atguigu'},//携带的数据(作为query参数)
dataType:'json',//配置响应数据格式
timeout:2000,//指定超时的时间
beforeSend:function (xhr) { // 设置请求头
// 如果后台没有跨域处理,这个自定义
xhr.setRequestHeader("myHeader","123456");
},
success:(result,reponseText,xhr)=>{
console.log(result,reponseText,xhr);
content.append(`<div>汽车名:${result.name},价格:${result.price}</div>`)
},//成功的回调
error:(xhr)=>{console.log('请求出错了',xhr);} //失败的回调
})
//使用jQuery发送ajax-get(精简版)
/* $.get('http://127.0.0.1:8080/test_jquery_get',{school:'atguigu'},(data)=>{
console.log(data);
content.append(`<div>汽车名:${data.name},价格:${data.price}</div>`)
},'json') */
})
btn2.click(()=>{
//使用jQuery发送ajax-post(完整版)
$.ajax({
url:'http://127.0.0.1:8080/test_jquery_post', //请求地址
method:'POST',//请求方式(默认值是GET)
data:{school:'atguigu'},//携带的数据
dataType:'json',//配置响应数据格式
timeout:2000,//指定超时的时间
success:(result,reponseText,xhr)=>{
console.log(result,reponseText,xhr);
content.append(`<div>汽车名:${result.name},价格:${result.price}</div>`)
},//成功的回调
error:(xhr)=>{console.log('请求出错了',xhr);} //失败的回调
})
//使用jQuery发送ajax-post(精简版)
$.post('http://127.0.0.1:8080/test_jquery_post',{school:'atguigu'},(data)=>{
console.log(data);
content.append(`<div>汽车名:${data.name},价格:${data.price}</div>`)
},'json')
})
</script>
</body>
</html>
11_演示回调地狱.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>11_演示回调地狱</title>
<script type="text/javascript" src="./js/jquery.min.js"></script>
</head>
<body>
<h3>该页面是测试:演示回调地狱(看代码)</h3>
<button id="btn1">点我发送请求(jQuery-ajax-get)</button>
<script type="text/javascript" >
const btn1 = $('#btn1')
btn1.click(()=>{
//使用jQuery发送ajax-get(精简版)
$.get('http://127.0.0.1:8080/test_jquery_get',{school:'atguigu'},(data)=>{
console.log(data);
$.get('http://127.0.0.1:8080/test_jquery_get',{school:'atguigu'},(data)=>{
console.log(data);
$.get('http://127.0.0.1:8080/test_jquery_get',{school:'atguigu'},(data)=>{
console.log(data);
},'json')
},'json')
},'json')
})
</script>
</body>
</html>
12_演示没有同源策略的危险场景.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<iframe id="baidu" src="https://www.baidu.com"></iframe>
<script type="text/javascript" >
const iframe = window.frames['baidu']
console.log(iframe);
</script>
</body>
</html>
13_jsonp解决跨域.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<h3>当前页面一定不要用服务器去打开,因为要制造跨域问题,用jsonp去解决</h3>
<button id="btn">点我获取数据</button>
<script type="text/javascript" >
const btn = document.getElementById('btn')
btn.onclick = ()=>{
//1.创建script节点
const scriptNode = document.createElement('script')
//2.给节点指定src属性(请求地址)
scriptNode.src = 'http://localhost:8080/test_jsonp?callback=peiqi'
//3.将节点放入页面
document.body.appendChild(scriptNode)
//4.准备好一个函数
window.peiqi = (a)=>{
console.log(a);
}
//5.移除已经使用过的script节点
document.body.removeChild(scriptNode)
}
</script>
</body>
</html>
14_jquery封装的jsonp.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Document</title>
<script type="text/javascript" src="./js/jquery.min.js"></script>
</head>
<body>
<h3>当前页面一定不要用服务器去打开,因为要制造跨域问题,jquery封装的jsonp</h3>
<button id="btn">点我获取数据</button>
<script type="text/javascript" >
const btn = $('#btn')
btn.click(()=>{
$.getJSON('http://localhost:8080/test_jsonp?callback=?',{},(data)=>{
console.log(data);
})
})
</script>
</body>
</html>
15_测试cors解决跨域.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>测试cors解决跨域</title>
</head>
<body>
<h3>当前页面一定不要用服务器去打开,因为要制造跨域问题,测试cors解决跨域</h3>
<button id="btn">点我获取数据</button>
<script type="text/javascript" >
const btn = document.getElementById('btn')
btn.onclick = ()=>{
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4){
if(xhr.status === 200){
console.log(xhr.response);
console.log(xhr.getAllResponseHeaders());
}
}
}
xhr.open('PUT','http://localhost:8080/test_put')
xhr.send()
}
</script>
</body>
</html>