Ajax,全称Asynchronous JavaScript And XML,简单来说就是异步的JS和XML;通过Ajax可以在浏览器中向服务器发送异步请求,最大的优势在于:无需刷新来获取数据
。
Ajax是一种将现有标准组合在一起使用的新方式。
XML,全称Extensible Makeup Language,被称为可拓展标记语言。
XML被设计用来传输
和存储
数据。
XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是自定义标签,用来表示一些数据。
比如说我有一个学生数据:
name ="小明"; age= 18 ; gender = "男";
用XML表示:
<student>
<name>小明name>
<age>18age>
<gender>男gender>
student>
只不过,现在已经被JSON替代了,例如上述例子用json表示:
{name :"小明",age: 18, gender : "男"}
优点
:
缺点:
HTTP(hypertext transport protocol)协议『超文本传输协议』﹐协议详细规定了浏览器和万维网服务器之间互相通信的规则。
格式 参数
请求行 : 包括:请求类型(GET、POST)\URL路径\HTTP协议的版本
请求头 : 包括:Host:XXX.com、Cookie:XXX、Content-type:application/x-www=form-urlencoded、User-Agent:chrome 83
空行 :
请求体: get请求,请求体为空;post则可以不为空,eg:username=admin&password=admin
格式:
响应行: 协议版本(http/1.1) 响应状态码(200) 响应字符串(OK)
响应头: Content-Type:text/hhtml;charset=utf-8;
Content-length:2048
Content-encoding:gzip
响应空行:
响应体:
列如:打开百度,搜索“你好”,查看具体的网络请求
ar btn = document.getElementsByClassName('btn')[0];
btn.onclick = () => {
// 发起Ajax 请求的步骤:
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化,设置请求的方法和url
xhr.open('GET', 'http://127.0.0.1:8000/get')
// 3.发送
xhr.send();
// 4.事件绑定,处理服务器返回的结果
// on = when 当...时候
/* readystate是xhr对象中的属性,表示状态,共有5个值:
0(未初始化)、
1(表示open方法已经调用完毕)、
2(表示send方法已经调用完毕)、
3(表示服务端返回部分的结果)、
4(表示服务端返回所有的结果),
*/
xhr.onreadystatechange = () => {
// 判断,是否服务端返回了所有的结果
if (xhr.readyState === 4) {
// 判断响应的状态码 200 404 401 403 500
// 2XX 都是成功
if (xhr.status >= 200 && xhr.status < 300) {
// 处理响应结果,应该包括:行+头+空行+体,但一般注重响应体
console.log(xhr.status)//状态码
console.log(xhr.statusText);//状态字符串
console.log(xhr.getAllResponseHeaders());//所有的响应头
console.log(xhr.response)//响应体
//将返回的结果进行赋值
// ....
} else {
// 处理响应失败的结果
}
}
}
}
// 2.初始化,设置请求的方法和url
xhr.open('GET', 'http://127.0.0.1:8000/get?a=100&b=400')
xhr.open('POST', 'http://127.0.0.1:8000/post')
// 3.发送
// POST形式的参数
// xhr.send('a=100&b=300');
xhr.send('a:100&b:300&c:1000');//请求体的格式,是非常灵活的
// 2.初始化,设置请求的方法和url
// xhr.open('GET', 'http://127.0.0.1:8000/get?a=100&b=400')
xhr.open('POST', 'http://127.0.0.1:8000/post')
// 设置请求头,接收两个参数:【头的名字,头的值】
/*
Content-Type:用来设置请求体类型的
*/
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('name', "aaaa")//该类型,为自定义的,如果需要,则要在后端设置允许接收的请求头类型
后端如下:
// all,可以接收任意类型的请求
app.all('/post', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置允许接收所有响应头类型
response.setHeader('Access-Control-Allow-Headers', '*')
console.log(request);
response.send("POST OK5")
})
整个实例前端代码:
btn.onclick = () => {
// 发起Ajax 请求的步骤:
// 1.创建对象
const xhr = new XMLHttpRequest();
// 2.初始化,设置请求的方法和url
// xhr.open('GET', 'http://127.0.0.1:8000/get?a=100&b=400')
xhr.open('POST', 'http://127.0.0.1:8000/post')
// 3.设置请求头,接收两个参数:【头的名字,头的值】
/*
Content-Type:用来设置请求体类型的
*/
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('name', "aaaa")
// 4.发送
// POST形式的参数
xhr.send('a=100&b=300');
// xhr.send('a:100&b:300&c:1000');//请求体的格式,是非常灵活的
// 5.事件绑定,处理服务器返回的结果
// on = when 当...时候
/* readystate是xhr对象中的属性,表示状态,共有5个值:
0(未初始化)、
1(表示open方法已经调用完毕)、
2(表示send方法已经调用完毕)、
3(表示服务端返回部分的结果)、
4(表示服务端返回所有的结果),
*/
xhr.onreadystatechange = () => {
// 判断,是否服务端返回了所有的结果
if (xhr.readyState === 4) {
// 判断响应的状态码 200 404 401 403 500
// 2XX 都是成功
if (xhr.status >= 200 && xhr.status < 300) {
// 处理响应结果,应该包括:行+头+空行+体,但一般注重响应体
console.log(xhr.status)//状态码
console.log(xhr.statusText);//状态字符串
console.log(xhr.getAllResponseHeaders());//所有的响应头
console.log(xhr.response)//响应体
// 设置返回结果
result.innerHTML = xhr.response
} else {
// 处理响应失败的结果
}
}
}
}
IE浏览器会对Ajax的请求结果缓存起来,当下一次请求的时候,请求的是本地的缓存,而非最新数据。因此,不利于对于时效性要求较高的场景
解决方法
:在url中加个获取目前时间,浏览器每次都会它当成新的请求,eg:‘http://127.0.0.1:8000/IE?t=’ + Date.now()
btn.addEventListener('click', function () {
// 1.初始化对象
const xhr = new XMLHttpRequest();
// 2.设置请求方法和路径,解决方法,在url中加个获取目前时间,浏览器每次都会它当成新的请求
xhr.open('GET', 'http://127.0.0.1:8000/IE?t=' + Date.now());
// 3.设置请求头
// 4.发送
xhr.send();
// 5.监听请求状态,对结果进行处理
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
results.innerText = xhr.response;
}
}
}
})
// 1.初始化对象
const xhr = new XMLHttpRequest();
// 超时2s,取消请求
xhr.timeout = 2000;
// 超时回调
xhr.ontimeout = () => {
alert("请求超时")
}
// 网络异常的回调
xhr.onerror = () => {
alert("网络出现异常")
}
// 2.设置请求方法和路径,解决方法,在url中加个获取目前时间,浏览器每次都会它当成新的请求
xhr.open('GET', 'http://127.0.0.1:8000/IE?t=' + Date.now());
let xhr = null;
btn1.onclick = () => {
console.log("发送请求")
// 发起Ajax
xhr = new XMLHttpRequest();
// 设置请求头
// 请求地址
xhr.open('GET', 'http://127.0.0.1:8000/IE');
// 发送
xhr.send();
// 监听发送完毕
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.response)
}
}
}
}
// abort
btn2.onclick = () => {
// console.log("取消请求");
xhr.abort();
}
解决关键:用标识符,来避免重复发送;如果正在发送,则把上一个取消掉;
const btn1 = document.getElementById('btn1');
let xhr = null;
// 用个标识符,来表示请求的状态
let isSendding = false;
btn1.onclick = () => {
console.log("发送请求")
if (isSendding) xhr.abort();//如果正在发送请求,则取消前一个请求,创建新的请求
// 发起Ajax
xhr = new XMLHttpRequest();
isSendding = true;
// 设置请求头
// 请求地址
xhr.open('GET', 'http://127.0.0.1:8000/IE');
// 发送
xhr.send();
// 监听发送完毕
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
isSendding = false;
if (xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.response)
}
}
}
}
<body>
<div class="container">
<button>GET方法</button>
<button>POST方法</button>
<button>通用型方法</button>
</div>
</body>
<script>
// get请求
$('button').eq(0).click(() => {
// get方法四个参数(url,参数,回调函数,响应体类型)
$.get('http://127.0.0.1:8000/getJosn', { a: 100, b: 100 }, data => {
console.log(data)
}, 'json')
})
// post请求
$('button').eq(1).click(() => {
$.post('http://127.0.0.1:8000/post', { a: 100, b: 100 }, data => {
console.log(data)
})
})
// 通用型
$('button').eq(2).click(() => {
$.ajax({
//url
url: 'http://127.0.0.1:8000/get',
// 参数
data: {
a: 100,
b: 200
},
// 头部信息
headers: {
},
// 请求类型
type: 'GET',
// 响应体类型
dataType: 'json',
// 成功的回调函数
success: data => {
console.log(data)
},
// 超时
timeout: 2000,
error: err => {
console.log(err)
}
})
})
</script>
<body>
<button>GET</button>
<button>POST</button>
<button>Ajax</button>
</body>
<script>
let btn = document.querySelectorAll('button');
// 配置baseUrl
axios.defaults
btn[0].onclick = () => {
axios.get('http://127.0.0.1:8000/getJosn',
{
// url参数
params: {
id: 100,
name: 'sss'
},
// 请求头参数
headers: {
age: 20
}
})
.then(
value => {
console.log(value)
}
)
}
btn[1].onclick = () => {
axios.post('http://127.0.0.1:8000/post', {
data: {
name: '小红',
age: '18'
}
}, {
// url参数
params: {
id: 100,
pwd: 123456
},
header: {
authurion: "ssdshsjcns",
}
})
}
// axios通用方式,发送Ajax请求
btn[2].onclick = () => {
axios({
url: 'http://127.0.0.1:8000/get',
method: 'GET',
params: {
id: 100
},
data: {
abc: 100
}
})
}
</script>
const btn = document.querySelector( ' button');
btn.onclick = function()i
fetch( 'http://127.0.0.1:8000/fetch-server?vip=10', i
//请求方法
method: "POST',//请求头
headers: {
name: "atguigu'}.
//请求体
body: 'username=admin&password=admin'
})
.then(response => i
return response.text();
})
.then(response=>{
console.log(response)
});
}
同源策略(Same-Origin Policy)最早由Netscape公司提出,是浏览器的一种安全策略。同源策略(同源策略)最早由Netscape公司提出,是浏览器的一种安全策略。
同源:
协议、域名、端口号必须完全相同。
违背同源策略就是跨域
。
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求。
在网页有一些标签天生具有跨域能力,比如:img link iframe script.
JSONP就是利用script
标签的跨域能力来发送请求的。
返回函数调用,让前端对该函数进行处理
前端:
<body>
用户名:<input type="text">
<p id="tips"></p>
</body>
<script>
const input = document.querySelectorAll('input');
const p = document.querySelectorAll('p');
function handle(data) {
console.log(data.name);
p[0].innerHTML = data.msg;
}
input[0].onblur = () => {
console.log('a')
// 先获取用户输入的值
let value = this.value;
// 发送该值的请求,在服务器检测该值是否符合
// 1.先创建script标签
const script = document.createElement('script');
// 2.设置src属性
script.src = 'http://127.0.0.1:8000/jsonp';
// 3.将script标签插入文档中
document.body.appendChild(script);
}
</script>
后端:
app.all('/jsonp', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置允许接收所有响应头类型
response.setHeader('Access-Control-Allow-Headers', '*')
// console.log(request);
data = {
name: '小红',
msg: '昵称已使用'
}
let str = JSON.stringify(data);
response.send(`handle(${str})`)
})
注意:
要在请求url中带上callback=?
<button>jquery发送jsonp请求</button>
<textarea id="result" name="" id="" cols="30" rows="10"></textarea>
<script>
$('button').eq(0).click(() => {
console.log('a')
// 注意使用jquery发送JSONp请求的时候,url地址后要带上:callback=?
$.getJSON('http://127.0.0.1:8000/jsonps?callback=?', data => {
console.log(data);
$('#result').html(`名称:${data.name}`)
})
})
</script>
服务器返回:也要先接收callback参数,再按执行函数的格式返回
app.all('/jsonps', (request, response) => {
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置允许接收所有响应头类型
response.setHeader('Access-Control-Allow-Headers', '*')
// console.log(request);
data = {
name: '小红',
msg: '昵称已使用'
}
let str = JSON.stringify(data);
// 接收callback参数
let cb = request.query.callback;
response.end(`${cb}(${str})`)
})
具体参见:
Cross-Origin Resource Sharing (CORS) - HTTP | MDN (mozilla.org)
CORS (Cross-Origin Resource Sharing),跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和 post 请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。
通过在服务端设置发送请求的请求头、请求方式等信息,来使用;
//设置响应头
response.setHeader( "Access-Control-Allow-origin","*");
response.setHeader("Access-Control-Allow-Headers", '*');
response.setHeader("Access-Control-Allow-Method",'*');
通过在服务端设置发送请求的请求头、请求方式等信息,来使用:
//设置响应头
response.setHeader( "Access-Control-Allow-origin","*");
response.setHeader("Access-Control-Allow-Headers", '*');
response.setHeader("Access-Control-Allow-Method",'*');