目录
1.重点掌握及知识要点
2.登录简单回顾
3.利用ajax来解决验证用户名问题
3.1ajax的基本使用
3.2案例实现通过ajax异步无刷新验证用户名
4.针对ajax的详细解释
4.1get注意点
4.1.1get传参的两种方式:queryString和/get/id
4.1.2queryString传参方式
4.1.3/get/id传参方式
4.2post传参方式
4.2.1post传参方式注意点
4.2.2post传参方式设置http正文头格式
4.2.3onload()方法中获取返还头部信息
4.2.4完整案例
4.3同步及异步ajax
4.4onload()
5.onreadystatechange——了解
5.1onreadystatechange
5.2readyState
5.3status常用状态码
5.4onreadystatechange示例:
5.5onload实现onreadystatechange功能
6.返还数据类型(XML,Json)
6.1获取原始数据xhr.response
6.2返还数据为json时xhr.responseText
6.3返还数据为json时,xhr.responseXML来获取
7.利用FormData对象来实现文件上传
7.1 创建FormData对象
7.2 监控上传进度——upload 事件
7.2.1upload事件下的各种事件——事件钩子
7.2.2监控文件上传进度示例
8.回顾
## 重点掌握
## 知识要点
ajax是: Ajax即“Asynchronous Javascript And XML”(异步 Javascript 和 XML)
let xhr = new XMLHttpRequest();
xhr.open("get","/checkUser",true); //true是异步,false是同步
xhr.onload = function(){let res = JSON.parse(xhr.responseText);}
xhr.send();
注意:
login.css:
.loginContainer{margin: 0 auto;width: 600px;text-align: center;padding-top: 20px;padding-bottom: 50px;border: 1px solid;
}
.loginContainer input{margin-bottom: 20px;
}
.loginStyle{width: 160px;height: 40px;background: rgb(50,203,77);color: white;font-size: 17px;
}
.inputStyle{width: 200px;height: 30px;padding: 5px;outline: none;
}.inputStyle:focus{border: 1px solid rgb(50,203,77);
}
form{position: relative;
}
.exchange{position: absolute;top:8px;right: 65px;color: red;display: none;
}
user.json:
[{"id":1,"username":"zhangsan","pwd":"123"},{"id":2,"username":"lisi","pwd":"123"}
]
login.js:
const Koa = require("koa");
const Router = require("koa-router");
const static = require("koa-static");
// const views = require("koa-views");
const userData = require("./data/user.json");let app = new Koa();
let router = new Router();app.use(static(__dirname + "/static"));
//前面页面直接放到static里时,只能通过login.html访问,不能通过/直接访问
router.get("/checkUser", (ctx, next) => {// 注意接收queryString参数通过cxt.query获得;如果是post传参需引入koa-bodyparser ,然后通过ctx.request.body接收let username = userData.find(item=>item.username === ctx.query.username);console.log(ctx.query);if(username){// node.js会自动将对象转为json传给前端,所以不用再进行转换ctx.body = {status:1,msg:"用户名正确"};}else{ctx.body = {status:0,msg:"用户名错误"};}
});app.use(router.routes());
app.listen("9090");
login.html:
登录
姓名:
密码:
通过http://localhost:9090/login.html即可请求道login.html页面
很多ajax框架都是基于XMLHttpRequest对象去实现的,但是很多框架也都存在一定问题,如axiso就不能实现文件或图片上传。
a标签,img标签中的src和script标签中的src都是使用get请求
传参方式注意点:
如上例。
注意queryString传参方式,通过ctx.query获取传递过来的参数。
传参方式:‘/请求地址/参数’
接收参数:‘/请求地址/:参数’ 接收地址,使用ctx.params获取参数值
login.js:get请求(/get/id传参方式)
//get请求(/get/id传参方式)
router.get("getInfo","/getInfo/:id",ctx=>{console.log(ctx.params);//{ id: '1' }ctx.body = {status:1,msg:"请求成功"};
});
post传参方式,如果需要发送数据,需要通过send(data)方法进行发送,发送给的数据是通过http正文头发送。
且post传参方式,node.js后台需要使用koa-body进行接收,ctx.request.body获取参数。
注意:如果post请求方式通过queryString方式传参,就需要通过ctx.query获取参数。
注意点:
发送数据时候需要设置http正文头格式:
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); //默认编码
xhr.setRequestHeader("Content-type","multipart/form-data"); //二进制编码,上传文件时使用
xhr.setRequestHeader("Content-type","application/json"); //json编码:传输数据也需要时JSON格式
示例:注意使用post请求时,后台必须使用koa-body模块,才能获取到参数
http正文头格式为默认编码时:
http正文头格式设置为JSON时:如果正文头是JSON格式,则传输数据也需要是json格式,必须使用JSON.stringify()将数据转为json格式
//正文请求头设置为json时,传输数据也需要是JSON格式xhr.setRequestHeader("content-type","application/json; charset=utf-8");let data = JSON.stringify({username:'zs',age:12});
后台获取post参数:需要引入koa-body,然后通过ctx.request.body接收参数
注意:ctx.body是ctx.response.body的别名,而ctx.request.body是post的传参。
const koaBody = require("koa-body");
app.use(koaBody());
//post请求
router.post("/getPostInfo",ctx=>{console.log(ctx.request.body);//{ username: 'zs', age: '20' }ctx.body = {status:1,msg:"请求成功"};
});
getAllResponseHeaders()获取所有头部信息(某些属性有可能会获取不到,大部分都能获取) 或者是getResponseHeader("请求头属性") 获取某个头部信息
xhr.onload = function(){console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}//获取所有头部信息console.log(xhr.getAllResponseHeaders());//获取某个头部信息console.log(xhr.getResponseHeader("content-type"));//application/json; charset=utf-8}
ajax_post.html:
login.js:
app.use(koaBody());
//post请求
router.post("/getPostInfo",ctx=>{console.log(ctx.request.body);//{ username: 'zs', age: '20' }ctx.body = {status:1,msg:"请求成功"};
});
结果:所有头部信息
date: Wed, 18 Sep 2019 01:59:50 GMT
connection: keep-alive
content-length: 33
content-type: application/json; charset=utf-8
异步:设置异步的请求不会影响其他请求或代码的执行
结果:按钮一的请求不会影响按钮二的打印结果(测试时网速太快看不到效果,可以将Network中的online网络改为slow3G再测)
异步:当设置同步执行时,其他请求或代码必须等该请求执行完后,才会进行执行
xhr.open("get","/getInfo/2",false);
结果:永远都只会先打印按钮一发送的请求后再执行按钮二的请求
以前是使用onreadystatechange后,通过readyState的状态判断是否请求完毕,现在使用onload()更加简洁方便。
onload()方法是异步的,即使写在send()方法前面也会再send()方法执行后才会执行,一般习惯上会将send()方法放在最后面。因为很多东西必须在send()之前设置才有用,如setRequestHeader()就必须在send()之前设置。
onreadystatechange:存有处理服务器响应的函数,每当 readyState 改变时,onreadystatechange 函数就会被执行。
readyState:存有服务器响应的状态信息。
HTTP状态码 | 描述 |
---|---|
100 | 继续。继续响应剩余部分,进行提交请求 |
200 | 成功 |
301 | 永久移动。请求资源永久移动到新位置 |
302 | 临时移动。请求资源零时移动到新位置 |
304 | 未修改。请求资源对比上次未被修改,响应中不包含资源内容 |
401 | 未授权,需要身份验证 |
403 | 禁止。请求被拒绝 |
404 | 未找到,服务器未找到需要资源 |
500 | 服务器内部错误。服务器遇到错误,无法完成请求 |
503 | 服务器不可用。临时服务过载,无法处理请求 |
其实,使用onload也有服务器响应信息和返回状态码:建议使用onload会更加简洁
xhr.onload = function(){console.log(xhr.readyState);//4console.log(xhr.status);//200console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}}
前端和后台之前,平台和平台之间数据传输都会使用同一的数据格式,现在主流的数据跨平台交互有XML和JSON。
//获取原始数据
console.log(xhr.response);
xhr.responseText //来获取
xhr.responseXML //获取值
示例:
前端HTML:
后台:
//获取XML数据
router.get("/getXMLInfo",ctx=>{ctx.set("content-type","text/xml");//注意这里反引号和xml内容不能换行ctx.body = `
});
结果:
为防止后台没有写XML的content-type,需要在前端重写XML格式:
xhr.overrideMimeType('text/xml;charset=utf-8');
注意点:
示例:
前端:注意上传文件是通过正文提交,所以必须使用post方式
后台:获取上传文件必须使用mutipart:ture;通过ctx.request.files.img获取文件
const Koa = require("koa");
const Router = require("koa-router");
const static = require("koa-static");
const koaBody = require("koa-body");
const fs = require("fs");let app = new Koa();
let router = new Router();
app.use(static(__dirname + "/static"));
//上传文件时,必须设置允许文件上传,否则接收不了
app.use(koaBody({multipart:true
}));//上传文件
router.post("/upload",ctx=>{//通过前端append()中的name属性即可获取到对应数据或文件// console.log(ctx.request.body);//{ username: '张三' }// console.log(ctx.request.files.img);//通过fs模块对相应文件进行转存即可//ctx.request.files.img.path即文件的临时路径,对临时路径中的文件转存到服务器下路径即可let fileData = fs.readFileSync(ctx.request.files.img.path);//文件转存时有可能出现文件夹权限问题,需要手动开启权限//判断文件夹不存在,需要先创建文件夹if(!fs.existsSync("static/imgs")){fs.mkdirSync("static/imgs/");}fs.writeFileSync("static/imgs/"+ctx.request.files.img.name,fileData);ctx.body = {status:1,msg:"文件上传成功"};
});app.use(router.routes());
app.listen("8888");
结果:{"status":1,"msg":"文件上传成功"}
以下事件都是在upload事件下:
注意点:
文件上传页面:
进度: 10% 速度:20b/s
后台处理:
//监控文件上传进度
router.post("/fileUpload",(ctx,next)=>{//通过前端append()中的name属性即可获取到对应数据或文件//ctx.request.files.imgFile.path即文件的临时路径,对临时路径中的文件转存到服务器下路径即可let fileData = fs.readFileSync(ctx.request.files.imgFile.path);//判断文件夹不存在,需要先创建文件夹if(!fs.existsSync("static/imgs")){fs.mkdirSync("static/imgs/");}fs.writeFileSync("static/imgs/"+ctx.request.files.imgFile.name,fileData);ctx.body = {status:1,msg:"文件上传成功"};
});
结果:
1.ajax基本使用:创建XMLHttpRequest对象,xhr.open(),xhr.onload,xhr.send()
2.get/post在ajax中的使用
3.ajax中成功的返还:onload
4.返还数据格式:response,responseText,responseXML
5.FormData对象:创建FormData对象,form.append(name,value)
6.upload事件对象:各个监控文件上传的事件方法