Ajax
全称:Asynchronous JavaScript And Xml
异步JS和XML
最大优势:无刷新获取数据
最开始传输数据用XML,现在已经被json字符串取代。
优缺点
优点:
- 可以无刷新页面与服务端进行通信
- 允许根据用户事件更新部分页面内容
缺点: - 没有浏览历史,不能回退
- 存在跨域问题
- SEO不友好(SEO:搜索引擎优化)
HTTP
请求报文
请求行:请求类型(GET/POST)/ url / 版本(HTTP/1.1)? 传递参数a=xx&b=xx
请求头:Host:
Cookie:
Content-type:
User-Agent:
名字,冒号,空格,值
空行
请求体:GET请求的请求体为空
POST请求的请求体可以不为空
响应报文
响应行:协议版本(HTTP/1.1) 状态码(200) 状态字符串(OK)
状态码:404找不到页面
403禁止
401未授权
500内部错误
200正常
……
响应头:对响应体内容进行一些描述
Content-Type:
Contemt-length:
Content-encoding:
……
空行
响应体
Ajax Express框架
基于Node.js平台,快速、开放‘极简的Web开发框架
简单使用
创建基本使用的js文件
//引入express
const express = require('express');
//创建应用对象
const app = express();
//创建路由规则
//request是对请求报文的封装
//response是对响应报文的封装
app.get('/' , (request,response)=>{
//设置响应头,设置允许跨域
response.setHeader('Access-Control-Allow-Origin','*');
//设置响应体
response.send('HELLO EXPRESS');
});
//监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动,8000端口监听中...");
})
打开控制台,通过node 基本使用.js来启动express
通过ctrl+c关闭
前端获取数据的方法:
GET:
function(){
//创建对象
const xhr = new XMLHttoRequest();
//初始化,设置请求的方法和url
xhr.open('GET','http://127.0.0.1:8000/server');
//发送
xhr.send();
//事件绑定 处理服务端返回的结果
//readystate是xhr对象中的属性,表示状态
//0 表示未初始化
//1 表示open方法调用完毕
//2 表示send方法调用完毕
//3 表示服务端返回部分结果
//4 服务端返回所有结果
xhr.onreadystatechange = function(){
//判断,如果服务端返回所有结果
if (xhr.state === 4) {
//判断响应状态码 200
//响应状态码以2打头都是成功
if (xhr.status 》= 200 && xhr.status < 300) {
//处理结果,行 头 体
//响应
console.log(xhr.status);//状态码
console.log(xhr.statusText);//状态字符串
console.log(xhr.getAllResponseHeaders());//所有响应头
console.log(xhr.response);响应体
}else{
}
}
}
}
POST:
服务器端要响应创建路由规则,不然会报错:
No ’Access-Control-Allow-Orign‘ header is present on
app.POST('/server',(request,response)=>{
response.setHeader('Access-Control-Allow-Orign','*');
response.send('Hello AJAX POST');
})
function(){
//创建对象
const xhr = new XMLHttpRequest();
//初始化
xhr.open('POST','http://127.0.0.1/server');
//设置请求头
//Content-Type请求体内容的类型
xhr.setRequestHeader('Content-Type','application/x-www-form');
//也可以添加自定义请求头,但是浏览器会有安全提示
//自定义请求头之后需要后端添加响应头
/*
后端添加:
response.setHeader('Access-Contol-Allow-Header','*');
允许所有类型请求头
app.post改成app.all
*/
//发送,带参数
//xhr.send('a:100&&b:200');也可以这样写
xhr.send('a=100&&b=200');//这种方式和json方式用的比较多
//处理返回结果
xhr.onreadystatechange = function(){
if(xhr.readystate == 4){
if(xhr.status >= 200 && xhr.status < 300){
//处理结果
}
}
}
}
如果后端返回json格式字符串
前端需要转成json对象
有两种方式转换:
//1. 手动转换:
JSON.parse(xhr.response);
//2. 自动转换,通过限制响应体数据类型
xhr.responseType = 'json';
nodemon工具
文件内容修改的时候自动帮助重新启动文档应用
IE缓存问题
IE浏览器会对Ajax的结果进行缓存,再次发送相同请求就会从缓存中得到数据,不会再次去后端查询。
但是对于一些时效性比较强的场景,这个缓存会影响我们的结果。
解决:
传递Date.now()参数,让每次请求都不同
xhr.open('GET','http://127.0.0.1/server?t=Date.now()');
请求超时与网络异常
//两秒钟没有结果,就取消请求
xhr.timeout = 2000;
//延时回调
xhr.ontimeout = funciton(){
alert('网络异常');
}
//网络异常回调
xhr.onerror = function(){
alert('网络异常');
}
取消请求
//abort()方法属于Ajax对象
xhr.abort();
请求重复发送
每点击一次就会发送一个请求,连续疯狂点击的时候服务器负载很大。
解决:再点击的时候,查看是否有请求正在发送,如果有,就取消之前的请求。
let isSending = false;//是否正在发送AJax请求
let xhr = null;
btn.onclick = function(){
//发送请求之前先判断是否有请求正在发送
if (isSending) xhr.abort();
//如果正在发送,则取消之前的请求,创建一个新的请求
xhr = new XMLHttpRequest();
//修改标识变量
isSending = true;
xhr.open('GET','http://127.0.0.1/server');
xhr.send();
xhr.onreadystatechange = function(){
if (x.readystate === 4) {
isSending = false;
//发送完成则修改标识符为false
}
}
}
Axios
目前前端最热门的工具库,vue和react推荐的Ajax请求工具包。
特性:
- node.js里面发送请求
- 支持promise(promise:es6推出的异步编程的新解决方案)
- 拦截器机制
- 取消请求
- 自动转json
- 数据转换
Axios发送Ajax请求:
在线引入:
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.js"></script>
配置baseURL
axios.default.baseURL = 'URL';
axios.get('url',{
params:{
name:'Tom',
age:100
},
headers:{
name: 'a'
}
}).then(res => {
});
axios({
method: 'POST',
url: 'URL',
//url参数,会体现到url中,常用于get请求
params: {
name: 'Tom',
age: 100
},
headers: {
a:100,
b:200
},
//请求体参数,不会体现到url中,常用于post请求
data: {
username: 'Tom',
age: 100
}
}).then(res => {
console.log(response);
//响应状态码
console.log(response.status);
//响应状态字符串
console.log(response.statusText);
//响应头信息
console.log(response.headers)
//响应体
console.log(response.data);
});
//设置参数还有很多
fetch()函数
fetch()函数属于全局对象,可以直接调用。
它返回一个promise,这个promise在请求响应后会被resolve,并传回response对象。
fetch('url',{
//请求方法
method: 'POST',
//请求头
headers: {
a: '100'
},
//请求体,GET或HEAD方法不能包含body信息
//不会显示到url中,要显示到url中可以去url中”?“后面添加
body: 'name=Tom&age:=100'
}).then(res => {
//返回响应体
//return response.text();
//自动解析成js对象
return response.json();
}).then(res => {
//输出响应体
console.log(response);
})
跨域
同源策略
同源:协议、域名、端口号必须完全相同
Ajax默认遵循同源策略
违背同源策略就是跨域
满足同源策略url可以简写
跨域解决方案 — JSONP
一个非官方的跨域解决方案,只支持get请求。
工作原理:
网页中有一些标签天生具有跨域能力,比如:img link iframe script
JSONP就是利用script标签的跨域能力来发送请求的
返回结果是一个函数的调用,函数的参数就是要返回的数据。
注意:函数要在前端提前声明
jQuery发送JSONP请求,在url后面要跟’?callback=?’
跨域解决方案 — CORS
跨域资源共享,官方跨域解决方案,不需要客户端做任何特殊操作,完全在服务器中进行处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
工作原理:
通过设置响应头告诉浏览器,该请求允许跨域,浏览器收到该响应。
响应头:
Access-Control-Allow-Origin
//接收哪些源站的请求
Access-Control-Expose-Headers
//暴露哪些响应头
Access-Control-Max-Age
//请求结果的缓存时间
Access-Control-Allow-Credentials
//是否允许携带cookie
Access-Control-Allow-Methods
//请求允许的方法,默认是get和post
Access-Control-Headers
//允许头信息