2MSL:两个时间单位,一来一回。两个时间单位里如果收到消息了,说明服务器还没有关,如果两个时间单位里没有收到消息,则说明服务器已经关闭了。
http协议(超文本传输协议):协议详细规定了浏览器和万维网服务器之间互相通信的规则。
请求行:请求行包括三部分:请求类型,url路径,HTTP协议的版本。请求类型有get、post、delete、put 、push
请求头(request header):请求头名称:请求头内容;即为key:value格式。比如:Host:localhost;Cookie:name = baidu ;Content-type(告知服务器请求是什么类型的):application/x-www-form-urlencode;等
请求体(request body)这次请求的主体信息。如果是get请求,请求体是空的;如果是post请求,请求体可以为空可以不为空。
请求报文:请求行+请求头+空行+请求体
响应行:包括三部分:HTTP协议版本,响应状态码,响应字符串
响应头(response header):格式和请求头格式一样。比如:Content-Type:text/html;charset=utf-8;Content-length:2048;Content-encoding:gzip;
属性一:content-type:内容的类型,后端向前端返回的数据类型
响应体(response body):真正的数据
响应报文:响应行+响应头+空行+响应体
Preview:做一个响应的预览,即响应的解析,对响应体内容解析之后的一个查看
Response:响应体,服务器返回的html内容
General
Response Headers(响应头):点击view source,得到响应行和响应头,响应体在response中
Request Headers(请求头):点击view source,就会得到请求行
From Data:当请求为post请求时,请求体携带的参数。点击 view source,原始的请求体内容
Query String Parameters(查询字符串参数),是对url中的参数做一个解析
js是单线程的语言,对于拿到的程序,只能一行一行的执行,如果上面的代码未执行,下面的代码就只能等待,这样的代码是同步(sync)的
结果为10,虽然定时器的时间为0,但是仍然是异步代码。异步代码总是在同步代码之后执行的。
Ajax前:用户触发一个http请求服务器,服务器收到后,作出响应到客户,并返回一个新的页面。所以说交互都是通过页面刷新或者页面跳转实现的。但这样的方式并不好,如果只是少量的数据更新,也会引发整个页面重新请求,浪费了很大一部分资源。
作用:专门用于网页和服务器之间交换数据的.(异步的javaScript和XML),是一种无需重新加载整个网页的情况下,能够更新部分网页的技术.。通过AJAX可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。
服务器:实质就是一台"提供了某种服务功能"的超级电脑
页面-------------Ajax-------------后台
(顾客----------服务员-----------厨房)
在后台计算的过程中,前端页面不受任何影响,因为他是一个异步请求,并不会因此而卡顿
readystate是xhr对象中的属性,表示状态 ,取值为0-4。
<body>
<button onclick="sendMsg()">发送请求</button>
<script>
function sendMsg(){
//1.创建一个XMLHttpRequest对象
let xhr = new XMLHttpRequest();
//2.调用open方法打开连接
// open 方法有三个参数:
//1.请求的method:一般为get,post等
//2.请求的url地址
//3.是否异步,默认为true,即默认异步,故而这个参数可以不用传
xhr.open('get','./data.php');
//3.发送请求(请求体)
xhr.send();
//4.监听状态的改变
//onreadystatechange这个事件会触发很多次,所以需要判断到底哪一次代表成功
xhr.onreadystatechange = function (){
//判断状态值:0-4;4代表最终的完成
if(xhr.readyState === 4){
//判断状态码
if (xhr.status === 200){
console.log(xhr.responseText);
}
}
}
}
</script>
</body>
echo ‘hello ajax’;
?>
返回了一个字符串
<body>
<button onclick="sendMsg()">发送请求</button>
<script>
function sendMsg(){
//1.创建一个XMLHttpRequest对象
let xhr = new XMLHttpRequest();
//2.调用open方法打开连接
// open 方法有三个参数:
//1.请求的method:一般为get,post等
//2.请求的url地址
//3.是否异步,默认为true,即默认异步,故而这个参数可以不用传
xhr.open('get','./data.php?id=1);
//3.发送请求
xhr.send();
//4.监听状态的改变
//onreadystatechange这个事件会触发很多次,所以需要判断到底哪一次代表成功
xhr.onreadystatechange = function (){
//判断状态值:0-4;4代表最终的完成
if(xhr.readyState === 4){
//判断状态码
if (xhr.status === 200){
console.log(xhr.responseText);
}
}
}
}
</script>
</body>
$id = $_GET[‘id’];
echo json_encode(array(
‘id’ => $id,
‘title’ => $’hello ajax’
))
?>
此时给前端返回的就是json格式的数据,{‘id’:’1’,’title’:’hello ajax’},实际上是一个字符串,即服务器返回的是一个满足json格式的字符串,因此需要对这个字符串进行解析
if (xhr.status === 200){
let resp = JSON.parse(xhr.responseText)
console.log(resp);
}
<body>
<button onclick="sendMsg()">发送请求</button>
<script>
function sendMsg(){
let xhr = new XMLHttpRequest();
//这里的方法改为:post
xhr.open('post','./data.php');
xhr.send();
xhr.onreadystatechange = function (){
if(xhr.readyState === 4){
if (xhr.status === 200){
console.log(xhr.responseText);
}
}
}
}
</script>
</body>
与get基本相同,只改变了open中的方法参数,由get改为了post
除了open里写post以外,还设置了请求头,把他的Content-type设置为urlencoded这种模式,这样设置以后,在发送参数时,就可以在send里按照编码的方式来发送
$name = $_POST[‘name’];
$age = $_POST[‘age’];
echo json_encode(array(
‘name’ => $name,
‘age’ => $age,
‘money’=> 999999
));
?>
请求行和请求体在上述代码都可以进行设置
使用setRequestHeader方法可以设置请求头,该方法接受两个参数,一个是头的名字,一个是头的值。
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
Content-Type:设置请求体内容的类型
当然,也可以自定义请求体(仅了解)
xhr.setRequestHeader('Name','zhangsan');
此时由于浏览器的安全机制会发现报错,这个时候就需要后端加一个特殊的响应头,*表示所有类型的头信息后端都能接受
response.setHeader('Access-Control-Allow-Headers','*');
如果此时还不行,因为会发送一个校验检查这个头信息可不可用。此时,后端可以将app.post改为app.all(可以接收任何类型的请求)
<body>
<div id="result"></div>
<script>
//绑定键盘按下事件
window.onkeydown = function () {
const result = document.getElementById('result');
//创建对象
const xhr = new XMLHttpRequest();
//设置响应体数据的类型(自动对数据进行转化)
xhr.responseType = 'json';
//初始化
xhr.open('GET','http://127.0.0.1:3000/json-server');
//发送
xhr.send();
//事件绑定
xhr.onreadystatechange = function () {
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
// console.log(xhr.response);
// result.innerHTML = xhr.response;
//手动对数据转化
// let data = JSON.parse(xhr.response);
// console.log(data);
// result.innerHTML = data.name;
//自动转化
console.log(xhr.response);
result.innerHTML = xhr.response.name;
}
}
}
}
</script>
</body>
手动对数据转化:使用parse()方法
自动对数据转化:设置响应体数据类型xhr.responseType = 'json';
//1.引入express
const express = require('express');
//2.创建应用对象
const app = express();
//3.创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.all('/json-server',(request,response)=>{
//设置响应头:设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//响应一个数据
const data = {
name: 'liming'
}
//对data对象进行字符串转换
let str = JSON.stringify(data);
//设置响应体
//send方法里只能接受字符串和buffer
response.send(str);
});
//4.监听端口启动服务
app.listen(3000,()=>{
console.log('服务已经启动,3000端口监听中...');
})
IE缓存问题:IE浏览器会对Ajax请求的结果做缓存,这样就会导致下次请求时的结果为本地的缓存,而不是最新数据。
解决方法:
发送请求时在url路径后面加一个时间戳,
xhr.open('GET','http://127.0.0.1:3000/ie?t='+Date.now());
原理:
Date.now():获取当前的时间戳
两次事件的时间戳不同,因此url也不同,那么浏览器就会认为这是两次不同的请求。这样,就会重新发一个新的请求,而不会去本地缓存中读取
请求超时回调:
xhr.ontimeout = function(){
alert('网络异常,请稍后重试!!');
}
网络异常回调:
xhr.onerror = function(){
alert('你的网络似乎出现了一些问题...')
}
btn.addEventListener('click',function () {
const xhr = new XMLHttpRequest();
//超时设置 (2s):如果2秒中之类,如果没有结果,那么这个请求就取消
xhr.timeout = 2000;
//超时回调
xhr.ontimeout = function(){
alert('网络异常,请稍后重试!!');
}
//网络异常回调
xhr.onerror = function(){
alert('你的网络似乎出现了一些问题...')
}
xhr.open('GET','http://127.0.0.1:3000/delay');
xhr.send();
xhr.onreadystatechange = function () {
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
result.innerHTML = xhr.response;
}
}
}
})
使用abort()方法
<button>点击发送</button>
<button>点击取消</button>
<script>
const btns = document.querySelectorAll('button');
let xhr = null;
btns[0].onclick = function () {
xhr = new XMLHttpRequest();
xhr.open('GET','http://127.0.0.1:8080/delay');
xhr.send();
}
//取消请求
btns[1].onclick = function () {
xhr.abort();
}
</script>
解决方法:设置一个标识符,做判断,将之间的请求取消掉
<button>点击发送</button>
<div id="result"></div>
<script>
const btns = document.querySelectorAll('button');
let xhr = null;
//标识变量
let isSending = false;//是否正在发送Ajax请求
btns[0].onclick = function () {
//判断标识变量:如果正在发送,就取消掉该(上一次)请求,创建新请求
if(isSending)
xhr.abort();
xhr = new XMLHttpRequest();
//修改标识符变量的值
isSending = true;
xhr.open('GET','http://127.0.0.1:3000/delay');
xhr.send();
xhr.onreadystatechange = function () {
if(xhr.readyState === 4){
//修改 标识变量的值
isSending = false;
if(xhr.status >= 200 && xhr.status < 300){
result.innerHTML = xhr.response;
}
}
}
}
</script>
同源策略:是浏览器的一种安全策略
同源:协议、域名、端口号必须完全相同
违背同源策略就是跨域
CORS通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。