异步的概念
异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念。
在我们学习的传统单线程编程中,程序的运行是同步的(同步不意味着所有步骤同时运行,而是指
步骤在一个控制流序列中按顺序执行)。而异步的概念则是不保证同步的概念,也就是说,一个异
步过程的执行将不再与原有的序列有顺序关系。
简单来理解就是:同步按你的代码顺序执行,异步不按照代码顺序执行,异步的执行效率更高。
以上是关于异步的概念的解释,接下来我们通俗地解释一下异步:异步就是从主线程发射一个子线
程来完成任务
同步:步骤在一个控制流序列中按顺序执行,不意味着所有步骤同时运行.
异步:是从主控制流序列【主线】开辟一个子控制流序列【副本】来完成任务。
同步程序执行效率低,异步程序执行效率高。
异步程序缺点:子线程脱离主线程控制,主线程不能判断子线程是否执行完毕,不子线程的执行结
果不能直接合并到主线程中。
什么时候用异步编程
在前端编程中(甚至后端有时也是这样),我们在处理一些简短、快速的操作时,例如计算 1 + 1
的结果,往往在主线程中就可以完成。主线程作为一个线程,不能够同时接受多方面的请求。所以,当一个事件没有结束时,界面将无法处理其他请求。
现在有一个按钮,如果我们设置它的 onclick 事件为一个死循环,那么当这个按钮按下,整个网页
将失去响应。
为了避免这种情况的发生,我们常常用子线程来完成一些可能消耗时间足够长以至于被用户察觉的
事情,比如读取一个大文件或者发出一个网络请求。因为子线程独立于主线程,所以即使出现阻塞
也不会影响主线程的运行。但是子线程有一个局限:一旦发射了以后就会与主线程失去同步,我们无法确定它的结束,如果结束之后需要处理一些事情,比如处理来自服务器的信息,我们是无法将
它合并到主线程中去的
为了解决这个问题,JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理
异步 AJAX
AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内
容
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行
AJAX 工作原理
AJAX 实例
例如:html页面发送http请求到服务器,得到一组学生信息,将得到的学生信息显示在html页面的表
格中
开发服务器程序
1.安装配置开发工具。
2.打开eclipse新建一个Maven项目
问题1:项目默认的java开发库版本【J2SE-1.5】与我们自己安装的java开发库版本【javase-1.8】
不一致
解决方法:在项目中的pom.xml配置插件
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
选中项目---右键---Maven---update project
问题2:web.xml is missing and <failOnMissingWebXml> is set to true
解决:在当前项目的src-->main-->webapp文件夹下创建WEB-INF文件夹;
在WEB-INF文件夹中创建web.xml文件
web.xml文件中的内容
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
</web-app>
3.创建构造学生信息的java类
创建保存java类的程序包“src/main/java”--右键--->new--->other--->java---package
“com.wangxing.javabean”
package com.wangxing.javabean;
/**
* 创建学生信息的java类
* @author Administrator
*
*/
public class Student {
private int stuid;
private String stuname;
private int stuage;
private String stuaddress;
public Student(int stuid,String stuname,int stuage,String stuaddress){
this.stuid=stuid;
this.stuname=stuname;
this.stuage=stuage;
this.stuaddress=stuaddress;
}
public int getStuid() {
return stuid;
}
public void setStuid(int stuid) {
this.stuid = stuid;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public int getStuage() {
return stuage;
}
public void setStuage(int stuage) {
this.stuage = stuage;
}
public String getStuaddress() {
return stuaddress;
}
public void setStuaddress(String stuaddress) {
this.stuaddress = stuaddress;
}
}
4.在项目的pom.xml文件中配置servlet的依赖库,和gson的依赖库
<dependencies>
<!-- 配置导入servlet的依赖库 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- 配置导入gson的依赖库 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
</dependencies>
5.编写请求处理程序
创建保存请求处理程序的程序包“src/main/java”--右键--->new--->other--->java---package
“com.wangxing.servlet”
package com.wangxing.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.wangxing.javabean.Student;
/**
* 请求的处理程序
* @author Administrator
*
*/
public class StudentServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建学生信息对象【一组】
Student stu1=new Student(1001,"zhangsan",23,"西安");
Student stu2=new Student(1002,"lisisi",24,"北京");
Student stu3=new Student(1003,"wangwu",25,"上海");
//创建保存学生信息的集合
List<Student> stulist=new ArrayList<Student>();
//装学生信息对象到集合
stulist.add(stu1);
stulist.add(stu2);
stulist.add(stu3);
//将装有学生信息对象到集合转换成json字符串
Gson gson=new Gson();
String studentjson=gson.toJson(stulist);
//设置请求对象/响应对象的字符编码
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
//创建输出流对象
PrintWriter out=resp.getWriter();
//写出json字符串
out.write(studentjson);
//关闭
out.close();
}
}
6.配置请求处理程序
WEB-INF/web.xml
<servlet>
<servlet-name>student</servlet-name>
<servlet-class>com.wangxing.servlet.StudentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>student</servlet-name>
<url-pattern>/getStudent</url-pattern>
</servlet-mapping>
7.在pom.xml配置tomcat服务器插件
<!-- 配置Tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 服务器访问端口号 -->
<port>8080</port>
<!--项目访问路径 -->
<path>/</path>
<!--服务器编码 -->
<uriEncoding>UTF-8</uriEncoding>
</configuration>
</plugin>
8.运行服务器
项目---》右键--》run as ---》Maven build---Goals:tomcat7:run
9.浏览器输入:http://localhost:8080/getStudent
页面开发
创建html页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script>
window.onload=function(){
//得到按钮对象
var butdom=document.getElementById("but1");
//绑定点击事件
butdom.onclick=function(){
//发起ajax请求
//1.创建XMLHttpRequest对象
//现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。
//老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象
var httpRequest=null;
if(window.XMLHttpRequest){
httpRequest=new XMLHttpRequest();
}else{
httpRequest=new ActiveXObject("Microsoft.XMLHTTP");
}
//2.建立连接
//通过XMLHttpRequest对象的open方法完成
//open(method,url,async)
//method---请求的类型;GET 或 POST
//url-----服务器的位置
//async---true(异步)或 false(同步)
httpRequest.open("GET","http://localhost:8080/getStudent",true);
//3.发送请求
//通过XMLHttpRequest对象的send方法完成
httpRequest.send();
//4.接收结果
//通过XMLHttpRequest对象的onreadystatechange回调函数
httpRequest.onreadystatechange=function(){
//判断服务器处理请求的阶段
//通过XMLHttpRequest对象的readyState属性
//0: 请求未初始化
//1: 服务器连接已建立
//2: 请求已接收
//3: 请求处理中
//4: 请求已完成,且响应已就绪
//判断请求是否处理成功
//通过XMLHttpRequest对象的status属性
//200: "OK" // 404: 未找到页面 //500: 服务器错误
if(httpRequest.readyState==4 && httpRequest.status==200){
//得到服务器返回的json字符串数据
//通过XMLHttpRequest对象的responseText属性
var data=httpRequest.responseText;
//处理json字符串
alert(data);
}
}
}
}
</script>
</head>
<body>
<input id="but1" type="button" value="获取学生信息"/><br>
<table id="maintable" border="1px"></table>
</body>
</html>
问题: Access to XMLHttpRequest at 'http://localhost:8080/getStudent' from origin 'null' has been
blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested
resource.[跨域资源共享 CORS]
[http://www.ruanyifeng.com/blog/2016/04/cors.html]
解决方法:
1.在当前html页面中进行设置【不推荐】
2.将http请求对象的设置交个服务器程序来完成
修改服务器程序
创建保存过滤器的程序包“com.wangxing.filte”
package com.wangxing.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class CORSFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "content-type,Authorization");
// response.setHeader("Access-Control-Allow-Credentials", "true");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
在web.xml配置CORSFilter 过滤器
注意:过滤器配置信息要写在servlet请求处理程序之前
<filter>
<filter-name>corsfilter</filter-name>
<filter-class>com.wangxing.filter.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>corsfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
XMLHttpRequest 对象
所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。
XMLHttpRequest 用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,
对网页的某部分进行更新
创建 XMLHttpRequest 对象
所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。
创建 XMLHttpRequest 对象的语法:
variable=new XMLHttpRequest();
老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:
variable=new ActiveXObject("Microsoft.XMLHTTP");
为了应对所有的现代浏览器,包括 IE5 和 IE6,请检查浏览器是否支持 XMLHttpRequest 对象。如
果支持,则创建 XMLHttpRequest 对象。如果不支持,则创建 ActiveXObject .
var xmlhttp;
if (window.XMLHttpRequest){
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlhttp=new XMLHttpRequest();
}else{
// IE6, IE5 浏览器执行代码
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
AJAX - 向服务器发送请求
如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法
xmlhttp.open("GET","ajax_info.txt",true);
xmlhttp.send();
方法 | 描述 |
open(method,url,async) | 规定请求的类型、URL 以及是否异步处理请求。 method:请求的类型;GET 或 POST url:文件在服务器上的位置 async:true(异步)或 false(同步) |
send(string) | 将请求发送到服务器。 string:仅用于 POST 请求 |
GET 还是 POST?
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,请使用 POST 请求:
无法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
GET 请求
xmlhttp.open("GET","/try/ajax/demo_get2.php?fname=Henry&lname=Ford",true);
xmlhttp.send();
POST 请求
xmlhttp.open("POST","/try/ajax/demo_post.php",true);
xmlhttp.send();
如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据.
xmlhttp.open("POST","/try/ajax/demo_post2.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send("fname=Henry&lname=Ford");
AJAX - 服务器 响应
如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。
属性 | 描述 |
responseText | 获得字符串形式的响应数据。 |
responseXML | 获得 XML 形式的响应数据。 |
AJAX - onreadystatechange 事件
当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时,就会触发 onreadystatechange 事件。
readyState 属性存有 XMLHttpRequest 的状态信息。
下面是 XMLHttpRequest 对象的三个重要的属性:
属性 | 描述 |
onreadystatechange | 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 |
readyState | 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。 0: 请求未初始化 1: 服务器连接已建立 2: 请求已接收 3: 请求处理中 4: 请求已完成,且响应已就绪 |
status | 200: "OK" |
onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。
当 readyState 等于 4 且状态为 200 时,表示响应已就绪.