同步与异步
1.同步
- 严格的按照先后顺序,一步接着一步的执行,等前面完成后才可以执行下一个
- 例如:食堂排队打饭
consolo.log("a");
consolo.log("b");
consolo.log("c");
2.异步
- 执行没有严格的先后顺序,两个或多个动作可以同时进行
- 例如:食堂排队打饭,但是我忘记带饭卡,先让后面同学先,我的饭卡到了我再排队打饭
consolo.log("a");
consolo.log("b");
consolo.log("c");
//异步操作
setTimeout(()=>{consolo.log("我的饭卡拿到了!")},2000);
consolo.log("d");
consolo.log("e");
====》 abcde 我的饭卡拿到了!
Ajax
1.概述
- 对原生XMLHttpRequest的封装
- 局部刷新技术
2.XMLHttpRequest
- Ajax技术核心
- 作用:发送请求到服务器,接收响应
- 函数
open(method,URL,async):与服务器建立连接
1.method:请求的HTTP方法,典型的有GET,POST
2.URL:请求的地址
3.async:是否使用异步请求 true/false 默认异步
setRequestHeader(header,value):设置请求头信息
setRequestHeader("HOST","www.baidu.com")//设置主机
setRequestHeader("AGENT","www.baidu.com")//设置请求头信息
setRequestHeader("Content-Type","application/x-www-form-urlencoded");
send(content):发送请求
1.GET只有这一种写法
req.open("GET","xxx.action?op=reg&name=zy&age=20&sex=男");
req.send();//写入的参数无效
2.POST两种写法都可以
req.open("POST","xxx.action")
req.send("op=reg&name=zy&age=20&sex=男");//当然也可以使用get的方式,但get不能只要此方式
- 属性
onreadystatechange : 绑定回调函数,当服务器有响应时会自动调用
req.onreadystatechange=function(){.....}
readystate :就绪状态码(引擎状态)
0 XMLHttpRequest对象没有完成初始化
1 XMLHttpRequest对象开始发送请求
2 XMLHttpRequest对象请求发送完成
3 XMLHttpRequest对象开始读取响应
4 XMLHttpRequest对象读取响应结果,请求响应成功
status :HTTP状态码(服务器状态)
200 服务器响应正常
300 重定向(服务器重新发送一个请求到另一个地址取数据)
400 无法找到请求的资源,服务器响应正常
403 没有访问权限
404 访问的资源不存在
500 服务器内部错误
responseText :获取响应的文本内容
responseXML :获取响应的XML文件
- 异步处理
var xmlHttp;
//创建该对象,根据不同的浏览器
function createXMLHttpRequest() {
if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();//王景浏览器的创建方式
}else if(window.ActiveXObject){
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");//IE浏览器的创建方式
}
}
window.onload = function () {
getTime();
getId();
}
function getTime() {
//创建请求对象
createXMLHttpRequest();
//绑定回调函数,当服务器有响应时会自动调用此函数
xmlHttp.onreadystatechange = handleStatechange;
//连接服务器
xmlHttp.open("GET","tools.action?op=date");
//发送请求
xmlHttp.send();
}
function handleStatechange() {
console.log("联机状态state:"+xmlHttp.readyState);
console.log("服务器状态:"+xmlHttp.status);
if(xmlHttp.readyState==4 && xmlHttp.status==200){
console.log(xmlHttp.responseText);
var json = eval("("+xmlHttp.responseText+")");//完成对象转换
if(json.code==1){
document.getElementById("time").innerHTML = "当前系统时间:"+json.data;
}
}
}
function getId() {
//创建请求对象
createXMLHttpRequest();
//绑定回调函数
xmlHttp.onreadystatechange = handleId;
//连接服务器
xmlHttp.open("POST","tools.action");
//通过post是如何编码参数,查文档ajax
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//发送请求
xmlHttp.send("op=number");
}
function handleId() {
if(xmlHttp.readyState==4 && xmlHttp.status==200){
var jsonObject = eval("("+xmlHttp.responseText+")");//完成对象转换
if(jsonObject.code==1){
document.getElementById("userid").innerHTML = jsonObject.data;
}
}
}
- 缺点
1.只有等服务器有响应(readyState=4,status=200)才会处理回调函数
2.没法控制顺序,若要保证顺序只能嵌套(太low)
3.两个异步请求时,后一个将前一个覆盖
解决:xmlHttp变成局部变量或es6 promise**
3.XMLHttpRequest+Promise
- promise
var xmlHttp;
//创建该对象
function createXMLHttpRequest() {
if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();//王景浏览器的创建方式
}else if(window.ActiveXObject){
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");//IE浏览器的创建方式
}
}
function promiseAjax(method,url,params) {
var pp = new Promise(function (resolve,reject){
createXMLHttpRequest();
xmlHttp.onreadystatechange = function () {
if(xmlHttp.readyState!=4)return;
if(xmlHttp.status==200){
resolve(xmlHttp.responseText);
}else{
reject("!!!");
}
}
xmlHttp.open(method,url);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlHttp.send(params);
});
return pp;
}
fetch
fetch直接回回送成功还是失败的信息
回送的data也是promise,需要then两次,第二次才会取到json字符串
1.get
fetch("tools.action?op=date").then(function (data) {
//data是一个promise对象
//data.text()是一个promise对象 只能访问一次
var promise = data.text();
return promise;
}).then(function (data) {
//这里的data才是真正的json字符串 上一个的结果文本
var jsonObject = eval("("+data+")");//完成对象转换
if (jsonObject.code==1){
document.getElementById("time").innerHTML = "当前系统时间:"+jsonObject.data;
}
})
2.post
fetch("tools.action?",{
method:"post",
body:"op=date",//也可以在在tools.action?后面
headers:{
"Content-Type":"application/x-www-form-urlencoded"
}
}).then(function (data) {
return data.text();
}).then(function (data) {
var jsonObject = eval("("+data+")");//完成对象转换
if (jsonObject.code==1){
document.getElementById("time").innerHTML = "当前系统时间:"+jsonObject.data;
}
})
Axios
1概述
- 基于promise的HTTP库 - promise
- 对Ajax的封装
- 插件,要额外下载
2.优点
- 从浏览器创建XMLHttpRequest
- 从node.js创建http请求
- 支持Promise的API:Promise的内容都可以用到
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御XSRF
3.get/post实现
1.get
axios.get("tools.action?op=date").then(function (data) {
console.log(data);
console.log(data.data);//json对象
console.log(data.data.code);
console.log(data.data.data);
});
2.post----1
axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded';
//有中文就要经过转码
axios({
method:'post',
url:"tools.action",
params:{
op:'number'
}
}).then(data => {
console.log(data.data.code+" "+data.data.data);
});
2.post----2
axios.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded';
var params = new URLSearchParams();
params.append('op','date');//包装一下参数
axios.post('tools.action',params).then(data=>{
console.log(data.data.code+" "+data.data.data);
})
3.all+spread
- 作用:在多个请求完成好后再执行一些逻辑
- 注意:是静态方法,不是实例方法
function getdate() {
return axios.get("tools.action?op=date");
}
function getnumber() {
var params = new URLSearchParams();
params.append('op','number');
return axios.post("tools.action",params);
}
axios.all([getdate(),getnumber()]).then(
axios.spread( (d1,d2) => {
console.log(d1);
console.log(d1.data.code+" "+d1.data.data);
console.log(d2);
console.log(d2.data.code+" "+d2.data.data);
})
)
Axios+Vue+Json
- 记得导入js(vue+axios)
1.html(页面样式没有)
- 注意箭头函数与普通函数中this的区别
const app = new Vue({
el:"#all",
data:{
time:'',
userid:'',
clientInfo:''
},
method:{
},
mounted:function () {//页面加载完
//当el元素页面加载完,就调用
axios.all([getdate(),getnumber(),getclientInfo()]).then(//方法在method中就要加this
axios.spread( (d1,d2,d3) => {
/**
* 此处注意箭头函数与匿名函数的区别
* 箭头函数内部的this是词法作用域,在编写函数时就已经确定
* 匿名函数的this指向运行时实际调用该方法的对象,无法在编写函数时确定
*/
this.$data.time = d1.data.data;
this.$data.userid = d2.data.data;
this.$data.clientInfo = d3.data.data;
})
);
},
});
function getdate() {//访问data,回送一个json字符串到页面上
return axios.get("tools.action?op=date");
}
function getnumber() {
var params = new URLSearchParams();
params.append('op','number');
return axios.post("tools.action",params);
}
function getclientInfo() {
return axios.get("tools.action?op=clientInfo");
}
2.Java
private void date(HttpServletRequest request, HttpServletResponse response){
Date date = new Date();
Format format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
JsonModel jsonModel = new JsonModel();
try {
jsonModel.setCode(1);
jsonModel.setData(format.format(date));
super.writeJson(jsonModel,response);
} catch (IOException e) {
e.printStackTrace();
jsonModel.setCode(0);
jsonModel.setMsg(e.getMessage());
}
}
private void number(HttpServletRequest request, HttpServletResponse response){
Random random = new Random();
JsonModel jsonModel = new JsonModel();
try {
jsonModel.setCode(1);
jsonModel.setData(random.nextInt(1000));
super.writeJson(jsonModel,response);
} catch (IOException e) {
e.printStackTrace();
jsonModel.setCode(0);
jsonModel.setMsg(e.getMessage());
}
}
private void clientInfo(HttpServletRequest request,HttpServletResponse response){
JsonModel jsonModel = new JsonModel();
try {
jsonModel.setCode(1);
String ip = request.getRemoteUser();
String agent = request.getHeader("User-Agent");
Map<String,String> data = new HashMap<String,String>();
data.put("ip",ip);
data.put("agent",agent);
jsonModel.setData(data);
super.writeJson(jsonModel,response);
} catch (IOException e) {
e.printStackTrace();
jsonModel.setCode(0);
jsonModel.setMsg(e.getMessage());
}
}
super.writeJson---------------------------------------------------------------
protected void writeJson(JsonModel jm, HttpServletResponse response) throws IOException {
//1.jm对象转成json字符串,第三方框架
Gson gson = new Gson();
String json = gson.toJson(jm);
//2.通过responce将json字符串写到页面上
response.setContentType("application/json;charset=utf-8");
PrintWriter out = response.getWriter();
out.println(json);
out.close();
}