JavaScript高级__异步编程--异步AJAX

一、异步的概念

异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念。

在我们学习的传统单线程编程中,程序的运行是同步的(同步不意味着所有步骤同时运行,而是指步骤在一个控制流序列中按顺序执行)。而异步的概念则是不保证同步的概念,也就是说,一个异步过程的执行将不再与原有的序列有顺序关系。

简单来理解就是:同步按你的代码顺序执行,异步不按照代码顺序执行,异步的执行效率更高。

以上是关于异步的概念的解释,接下来我们通俗地解释一下异步:异步就是从主线程发射一个子线程来完成任务。

同步:步骤在一个控制流序列中按顺序执行,不意味着所有步骤同时运行.

异步:是从控制流序列【主线】开辟一个子控制流序列【副本】来完成任务。

同步程序执行效率低,异步程序执行效率高。

异步程序缺点:子线程脱离主线程控制,主线程不能判断子线程是否执行完毕,不子线程的执行结果不能直接合并到主线程中。

二、 什么时候用异步编程

在前端编程中(甚至后端有时也是这样),我们在处理一些简短、快速的操作时,例如计算 1 + 1 的结果,往往在主线程中就可以完成。主线程作为一个线程,不能够同时接受多方面的请求。所以,当一个事件没有结束时,界面将无法处理其他请求。

现在有一个按钮,如果我们设置它的 onclick 事件为一个死循环,那么当这个按钮按下,整个网页将失去响应。

为了避免这种情况的发生,我们常常用子线程来完成一些可能消耗时间足够长以至于被用户察觉的事情,比如读取一个大文件或者发出一个网络请求。因为子线程独立于主线程,所以即使出现阻塞也不会影响主线程的运行。但是子线程有一个局限:一旦发射了以后就会与主线程失去同步,我们无法确定它的结束,如果结束之后需要处理一些事情,比如处理来自服务器的信息,我们是无法将它合并到主线程中去的。

为了解决这个问题,JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理。

三、异步AJAX 

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。

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更新项目

     问题二: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”--右键-->newther--->java---package--“com.wangxing.javabean”

package com.wangxing.javabean;
/*
 创建学生信息的java类
 */
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的依赖库

servlet依赖包的概念

称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。 简单来说,Servlet是服务器端的一段程序(代码、功能实现),可交互式的处理客户端发送到服务器的请求,并完成操作响应。并支持动态网页技术。JavaWeb程序开发的基础,JavaEE规范(一套接口)的一个组成部分。它是由服务器厂商实现的。

gson的依赖库概念

Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的Java类库。 可以将一个 Json 字符转成一个 Java 对象,或者将一个 Java 对象转化为 Json 字符串。

<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.5</version>
		</dependency>
</dependencies>

5.编写请求处理程序

      创建保存请求处理程序的程序包“src/main/java”--右键--->new--->other--->java---package

“com.wangxing.servlet”---class--StudentSrevlet .class(请求处理程序)

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
 */
//使用extends接口将servlet的依赖包待得HttpServlet类继承给StudentSrevlet类上
public class StudentSrevlet extends HttpServlet {
	//通过继承过来的类找到适用的方法(请求处理)
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		super.doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//将处理程序的请求卸载dopost方法中
		//创建学生信息对象【一组】
		Student stu1 = new Student(1001,"fxt",22,"西安");
		Student stu2 = new Student(1002,"ch",22,"西安");
		Student stu3 = new Student(1003,"htt",23,"上海");
		//创建保存学生信息的集合
		List<Student>stulist=new ArrayList<Student>();
		//将学生信息装进集合中
		stulist.add(stu1);
		stulist.add(stu2);
		stulist.add(stu3);
		//将装有学生信息对象到集合转换成json字符串
		//因为浏览器页面识别不了java对象
		Gson gson=new Gson();
		String studentjson=gson.toJson(stulist);
		//设置请求对象/相应对象的字符编码
		req.setCharacterEncoding("utf-8");
		req.setCharacterEncoding("utf-8");
		//创建输出流对象
		PrintWriter out = resp.getWriter();
		//写出json字符串
		out.write(studentjson);
		//关闭
		out.close();
	}
	
}

6.配置请求处理程序在WEB-INF/web.xml

        servlet和servlet-mapping的作用:

       

访问顺序为1—>2—>3—>4,其中2和3的值必须相同。

url-pattern 标签中的值是要在浏览器地址栏中输入的 url,可以自己命名,这个 url 访问名为 servlet-name 中值的 servlet,两个 servlet-name 标签的值必须相同,因为通过 servlet 标签中的 servlet-name 标签映射到 servlet-class 标签中的值,最终访问 servlet-class 标签中的 class。
还有,web.xml 的 / 表示的是http://localhost:8080/ + 工程名
而.jsp页面的action,加了/表示绝对路径http://localhost:8080/ ,没有加 / 表示的是相对路径

<servlet>
  	<servlet-name>student</servlet-name>
  	<servlet-class>com.wangxing.servlet.StudentSrevlet</servlet-class>
  </servlet>
<servlet-mapping>
  	<servlet-name>student</servlet-name>
  	<url-pattern>/getstudentinfo</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 得到json数据此时浏览器编码和字符串流编码不一致

 前端页面开发

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta charset="utf-8">
        <script>
            window.onload=function(){
                //得到按钮对象
                var btu1dom=document.getElementById("btu1");
                //给按钮对象绑定点击事件
                btu1dom.onclick=function(){
                    //发起ajax请求
                    //1.创建XMLHttpRequest对象
                        //现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象。
                        //老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象
                        //设置一个变量接收判断后的请求方法
                        var httpresquest=null;
                        if(window.XMLHttpRequest){
                            httpresquest=new XMLHttpRequest();
                        }else{
                            httpresquest=new ActiveXObject("Microsoft.XMMLHTTP");
                        }
                        //2.建立连接
                        //通过XMLHttpRequest对象的open()方法完成
                        //open(method,url,async)
                        //method---请求的类型;GET 或 POST
                        //url-----服务器的位置
                        //async---true(异步)或 false(同步)
                        httpresquest.open("GET","http://localhost:8080/getStudent",true);
                        //3.发送请求
                        //通过XMLHttpRequest对象的send方法完成
                        httpresquest.send();
                        //4.接收结果
                        //通过XMLHttpRequest对象的onreadystatechange回调函数完成
                        httpresquest.onreadystatechange=function(){
                            //判断服务器处理请求的阶段
                            //通过XMLHttpRequest对象的readyState属性
                            //0: 请求未初始化
                            //1: 服务器连接已建立
                            //2: 请求已接收
                            //3: 请求处理中
                            //4: 请求已完成,且响应已就绪
                            //判断请求是否处理成功
                            //通过XMLHttpRequest对象的status属性
                            //200: "OK"  // 404: 未找到页面  //500: 服务器错误
                            if(httpresquest.readyState==4 && httpresquest.status==200){
                                //得到服务器返回的json字符串数据
                                //通过XMLHttpRequest对象的responseText属性
                                var data=httpresquest.responseText;
                                //处理json字符串
                                //将JSON字符串转换成JSON对象
                                var dataobj= JSON.parse(data);
                                //alert(dataobj);//[object Object],[object Object],[object Object]是一个数组里面三个对象
                                //遍历数组
                                var tabdom= document.getElementById("maintable");
                                //设置表头
                                var tableth=("<tr><td>studi</td><td>stuname</td><td>stuage</td><td>address</td></tr>")
                                //设置接收每一行数据的变量
                                var tabbody ="";
                                for(da in dataobj){
                                    //将每次得到的数据添加到前面的数据后面
                                   tabbody +="<tr><td>"+(dataobj[da].stuid)+"</td>"+"<td>"+(dataobj[da].stuname)+"</td>"+"<td>"+(dataobj[da].stuage)+"</td>"+"<td>"+(dataobj[da].stuaddress)+"</td>"+"</tr>";
                                }
                                alert(tabbody)
                                table=tableth+tabbody;
                                //alert(table)
                                tabdom.innerHTML=table
                            }
                        }
                }
            }
        </script>
    </head>
    <body>
        <input type="button" value="请求获取学生信息" id="btu1">
        <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. 给服务器程序添加一哥过滤器达到跨域资源共享,给所有服务器请求加一个安监解决跨域资源错误

修改服务器程序

创建保存过滤器的程序包“com.wangxing.filte”

extends 是继承某个类, 继承之后可以使用父类的方法, 也可以重写父类的方法

implements 是实现多个接口, 接口的方法一般为空的, 必须重写才能使用 

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 {
	  }

	  // TODO:这里应该是只需要处理OPTIONS请求即可~~~
	  @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>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值