热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

前后端交互一(ajax基本使用,XMLHttpRequest对象实现数据交互,onreadystatechange服务器响应信息,FormData对象上传文件,upload事件对象)

目录1.重点掌握及知识要点2.登录简单回顾3.利用ajax来解决验证用户名问题3.1ajax的基本使用3.2案例实现通过ajax异步无刷新验证用户名4.针对ajax的详

目录

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.回顾




1.重点掌握及知识要点

## 重点掌握


  1. 理解ajax基本使用
  2. 会使用XMLHttpRequest对象实现数据交互
  3. 了解onreadystatechange服务器响应信息(状态码)
  4. 会使用FormData对象上传文件
  5. 了解upload事件对象(XMLHttpRequest下的事件对象)

## 知识要点


  1. ajax使用
  2. XMLHttpRequest对象
  3. FormData对象
  4. upload 事件对象

2.登录简单回顾


  1. 提出ajax验证用户名需求;
  2. 验证错误后,如果通过跳转解决很麻烦;
  3. 各种跳转用户体验差

3.利用ajax来解决验证用户名问题

ajax是: Ajax即“Asynchronous Javascript And XML”(异步 Javascript 和 XML)


3.1ajax的基本使用


  • 新建XMLHttpRequest对象;

 let xhr = new XMLHttpRequest();

  • 配置请求参数

 xhr.open("get","/checkUser",true); //true是异步,false是同步

  • 接收返还值

  xhr.onload = function(){let res = JSON.parse(xhr.responseText);}

  • 发送服务器请求

xhr.send();

3.2案例实现通过ajax异步无刷新验证用户名

注意:


  1. 通过 XMLHttpRequest对象中open()方法发起请求。xhr.open("get","/checkUser?username="+this.value,true); //true表示异步发送请求,false同步发送请求,默认为false,所以必须设置为true
  2. 通过 XMLHttpRequest对象中onload()方法获取返还数据。注意返回数据是从XMLHttpRequest对象中获得的,xhr.responseText(获取json数据)和xhr.response(获取原始数据),xhr.responseXML(获取XML数据)都可以获取返还数据
  3. 获取到的数据是JSON格式的,需要将其转为对象。JSON.parse(xhr.responseText).msg
  4. 后台接收queryString参数通过cxt.query接收;如果是post普通数据传参只需引入koa-body模块,后台通过ctx.request.body接收;如果是post传参且上传文件需引入koa-bodyparser ,然后通过ctx.request.body接收

 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页面 


4.针对ajax的详细解释

很多ajax框架都是基于XMLHttpRequest对象去实现的,但是很多框架也都存在一定问题,如axiso就不能实现文件或图片上传。


4.1get注意点


  • get通过parmas传参
  • get和querystring的问题,通过url传参

a标签,img标签中的src和script标签中的src都是使用get请求


4.1.1get传参的两种方式:queryString和/get/id


  1. queryString,通过queryString传参有长度限制,默认为2048
  2. /get/id

传参方式注意点:


  • querystring传参和get/post请求方式是两个概念,不是使用querystring传参就是get请求,post也可以通过querystring进行传参;通过ctx.query获取传递过来的参数
  • 通过querystring方式进行传参时,后台接收地址不受影响;但如果使用/get/id方式传参,后台必须通过/get/:id方式接收参数,并通过ctx.params获得参数值;

4.1.2queryString传参方式

如上例。

注意queryString传参方式,通过ctx.query获取传递过来的参数。


4.1.3/get/id传参方式

传参方式:‘/请求地址/参数’ 

接收参数:‘/请求地址/:参数’ 接收地址,使用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:"请求成功"};
});

4.2post传参方式

post传参方式,如果需要发送数据,需要通过send(data)方法进行发送,发送给的数据是通过http正文头发送。

且post传参方式,node.js后台需要使用koa-body进行接收,ctx.request.body获取参数。

注意:如果post请求方式通过queryString方式传参,就需要通过ctx.query获取参数。


4.2.1post传参方式注意点


  • post一般不通过queryString进行传参,因为queryString传参有长度限制(服务器会限制),默认2048。
  • 发送数据时候需要设置http正文头格式:post传参是通过HTTP正文进行传参,正文传参必须设置编码格式。同form表单的默认编码格式    。form表单中可以省略,但是ajax请求时不能省略。
  • 需要手动设置正文头,setRequestHeader()的content-type为json且发送的数据通过JSON.stringtify()进行处理,传递过去的数据node才会以对象进行接收。如果没有设置也可以接收,但是需要通过queryString模块ctx.query进行处理,但是前端这样传递数据不好。

注意点:


  1. 发送数据时候需要设置http正文头格式;
  2. 获取头部信息:getAllResponseHeaders  或者是getResponseHeader ;

4.2.2post传参方式设置http正文头格式

发送数据时候需要设置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:"请求成功"};
});

4.2.3onload()方法中获取返还头部信息

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}

4.2.4完整案例

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


4.3同步及异步ajax


  • 设置异步的请求不会影响其他请求或代码的执行;
  • 当设置同步执行时,其后其他请求或代码必须等该请求执行完后,才会进行执行

异步:设置异步的请求不会影响其他请求或代码的执行


结果:按钮一的请求不会影响按钮二的打印结果(测试时网速太快看不到效果,可以将Network中的online网络改为slow3G再测)

异步:当设置同步执行时,其他请求或代码必须等该请求执行完后,才会进行执行

xhr.open("get","/getInfo/2",false);

 结果:永远都只会先打印按钮一发送的请求后再执行按钮二的请求


4.4onload()

以前是使用onreadystatechange后,通过readyState的状态判断是否请求完毕,现在使用onload()更加简洁方便。

onload()方法是异步的,即使写在send()方法前面也会再send()方法执行后才会执行,一般习惯上会将send()方法放在最后面。因为很多东西必须在send()之前设置才有用,如setRequestHeader()就必须在send()之前设置。


5.onreadystatechange——了解


5.1onreadystatechange

onreadystatechange:存有处理服务器响应的函数,每当 readyState 改变时,onreadystatechange 函数就会被执行


5.2readyState

readyState:存有服务器响应的状态信息。


  • 0: 请求未初始化(代理被创建,但尚未调用 open() 方法)
  • 1: 服务器连接已建立(`open`方法已经被调用)
  • 2: 请求已接收(`send`方法已经被调用,并且头部和状态已经可获得)
  • 3: 请求处理中(下载中,`responseText` 属性已经包含部分数据)
  • 4: 请求已完成,且响应已就绪(下载操作已完成)

5.3status常用状态码


status常用状态——http状态码
HTTP状态码描述

100

继续。继续响应剩余部分,进行提交请求

200

成功

301

永久移动。请求资源永久移动到新位置

302

临时移动。请求资源零时移动到新位置

304

未修改。请求资源对比上次未被修改,响应中不包含资源内容

401

未授权,需要身份验证

403

禁止。请求被拒绝

404

未找到,服务器未找到需要资源

500

服务器内部错误。服务器遇到错误,无法完成请求

503

服务器不可用。临时服务过载,无法处理请求


5.4onreadystatechange示例: 



5.5onload实现onreadystatechange功能

其实,使用onload也有服务器响应信息和返回状态码:建议使用onload会更加简洁

xhr.onload = function(){console.log(xhr.readyState);//4console.log(xhr.status);//200console.log(xhr.responseText);//{"status":1,"msg":"请求成功"}}

6.返还数据类型(XML,JSON) 

前端和后台之前,平台和平台之间数据传输都会使用同一的数据格式,现在主流的数据跨平台交互有XML和JSON。


6.1获取原始数据xhr.response

//获取原始数据
console.log(xhr.response);

6.2返还数据为json时xhr.responseText


  • 服务器返还json数据:xhr.responseText 来获取

xhr.responseText //来获取

6.3返还数据为json时,xhr.responseXML来获取 


  • 服务器返还xml数据 :

  1. xhr.responseXML //获取值
  2. 服务器端设置response里的content-type内容ctx.set("content-type","text/xml");
  3. 前端重写XML(以防后台没有指定content-type类型):xhr.overrideMimeType('text/xml;charset=utf-8');注意属性之间不能有空格
  4. 前端和服务器端随便那边设置返还数据格式即可,不需要都设置

xhr.responseXML //获取值

 示例:

前端HTML:


后台:

//获取XML数据
router.get("/getXMLInfo",ctx=>{ctx.set("content-type","text/xml");//注意这里反引号和xml内容不能换行ctx.body = `nodeJS实战52.0元react进阶56.0元`;
});

 结果:

为防止后台没有写XML的content-type,需要在前端重写XML格式:

xhr.overrideMimeType('text/xml;charset=utf-8');

7.利用FormData对象来实现文件上传


7.1 创建FormData对象

注意点:


  1. 通过files属性获取到的是类数组;
  2. 通过new FormData()创建文件上传对象;
  3.  formData.append(name,value);name必须和后台接收时name保持一致,value可以是文件也可以是普通数据
  4. 文件上传必须通过正文方式进行传递,所以必须使用post请求;
  5. 使用FormData时会自动对content-type进行设置,就不需要再进行手动设置
  6. 后台接收数据时,通过前端append()中的name属性即可获取到对应数据或文件
  7. 再通过fs模块对相应文件进行转存即可。ctx.request.files.img.path即文件的临时路径,对临时路径中的文件转存到服务器下路径即可
  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":"文件上传成功"}


7.2 监控上传进度——upload 事件


7.2.1upload事件下的各种事件——事件钩子

以下事件都是在upload事件下:


  • onloadstart   上传开始
  • onprogress  数据传输进行中(evt.total :需要传输的总大小;evt.loaded :当前上传的文件大小;)
  • onabort 上传操作终止(取消上传xhr.abort())
  • onerror  上传失败
  • onload 上传成功
  • onloadend 上传完成(不论成功与否)

7.2.2监控文件上传进度示例

注意点:


  • 使用标签可以显示文件上传进度
  • 监控文件上传速度(需要onloadstart和onprogress的时间差,及时间差内文件已上传的文件大小),当前文件大小/时间差 即文件上传速度;时间差需要转为单位为秒
  • evt.total :需要传输的总大小;evt.loaded :当前上传的文件大小
  • 需要处理上传的单位b/s ,判断文件足够大时使用kb/s;

文件上传页面:





进度:  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:"文件上传成功"};
});

 结果:


8.回顾

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事件对象:各个监控文件上传的事件方法


推荐阅读
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • python限制递归次数(python最大公约数递归)
    本文目录一览:1、python为什么要进行递归限制 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
author-avatar
吴素婷76625
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有