Ajax使用教程及JSON格式介绍

第十一章 AJAX和JSON

1.AJAX

Asynchronous JavaScript and XML

异步的js和xml

1. 创建异步请求的步骤

  1. 创建异步请求

    let request
    
    //1)此函数用来创建异步请求
    function create(){
        //创建一个异步请求
        /*
        *   这种创建方式是level2版本的创建方式,如果要针对ie6 7 8 等老旧浏览器
        *   则应该使用level1版本
        *
        *   if(window.XMLHttpRequest){
        *       request = new XMLHttpRequest()
        *   }else{
        *       request = new ActiveXObject("Microsoft.XMLHttp")
        *   }
        *
        *   同步请求:
        *       HttpServletRequest
        *       ServletRequest
        * */
    	request = new XMLHttpRequest()
    }
    
  2. 创建函数用来发送请求

    //2)此函数用来给服务器发送请求,一般称之为主函数(非官方)
    function checkName(value){
    	//A:创建异步请求
    	create()
        //B:给服务器发送异步请求
        /*
        *   request.open(type,url,async)
        *
        *   url:表示发送异步请求的目的地(拦截地址)
        *       如果是get,则从此处传递值
        *       本例:
        *           'check?key=value&key2=value2'
        *   type:请求类型 post get
        *   async:表示是否使用异步,默认true使用,更改为false则使用同步,当响应返回之前
        *   浏览器锁死,用户无法进行任何操作
        * */
    	request.open('post','check',true)
        //C:如果使用POST则需要书写此句,表示使用字符流进行值的传递,GET自动字符流不需要书写
        request.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
        //D:声明回调函数
        //注意这里函数名可以随意书写,但是没有括号,如果存在括号则表示调用,没有括号表示声明
        //调用立刻执行,而声名需要前面的条件满足才可以
        request.onreadystatechange = callback
        //E:设置传递的参数,注意POST从此处传递值,GET不从此处传值,也必须书写,填写null
        //request.send('etoak='+value)
        request.send(`etoak=${value}`)
    }
    
  3. 书写回调函数接受响应信息

    readyState状态

    readyState值状态补充描述
    0链接尚未初始化调用request.oprn()
    1链接初始化请求已经准备好
    2请求正在处理服务器正在处理请求时会做出一个相应,readyState=2时,响应收不提供一个关于响应的信息,并提供一个状态码
    3得到服务器的响应这个阶段数据下载到请求对象,但是响应数据还没有准备好,不能使用
    4服务器响应准备就绪现在服务器处理完请求数据可以使用了

    status状态

    状态码描述
    1xx消息
    2xx成功
    3xx重定向
    4xx请求错误404 405
    5xx服务端异常 500

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7WBX7wxj-1594441116061)(D:\Study\Yitu\前端\AJAX\AjaxDaysOfficial\attachment\ajax回调函数.jpg)]

    //3)回调函数,接受服务器处理完的响应信息
    function callback(){
    	//首先判断服务器发送数据是否完整
        if(request.readyState==4){
            //完整的返回的数据没有报错
            if(request.status==200){
                //接受返回的字符串
                let value = request.responseText
    
                //拿取span元素
                let nodeSpan = document.getElementById('name_msg')
    
                //拿取submit表单元素
                let nodeSub = document.getElementById('sub')
    
                if(value=='bingo'){
                    //设置错误提示信息
                    nodeSpan.innerHTML = '<img src="image/wrong.png">用户姓名已经被占用'
                    //设置样式
                    nodeSpan.style.color = 'red'
                    //禁用提交按钮
                    nodeSub.disabled = true
                    return;
                }
                nodeSpan.innerHTML = '<img src="image/right.png">用户姓名可以使用'
                nodeSpan.style.color = 'green'
                nodeSub.disabled = false
            }
        }
    }
    
@WebServlet("/check")
public class CheckName extends HttpServlet {
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/*
		*   Ajax支持三种数据的输出
		*       1)字符串               text/plain
		*       2)xml                 text/xml
		*       3)json                application/json
		*       所以在这里不管怎么书写也不能书写text/html,因为根本不支持html
		* */
		response.setContentType("text/plain;charset=utf-8");
		request.setCharacterEncoding("utf-8");

		//拿取要输出的字符流
		PrintWriter out = response.getWriter();

		//接受提交过来的用户名
		String name = request.getParameter("etoak");

		//模拟数据库查询
		if(name.equalsIgnoreCase("elena")){
			/*
			*   返回字符串
			*   out.print(要返回的数据)
			*   只支持 字符串 json xml
			*   注意不能使用println()否则会自动添加\n
			* */
			out.print("bingo");
			out.close();
			return;
		}
		out.print("suc");
		out.close();
	}

注意点

  1. servlet只能书写一下三种MIME标签

Ajax支持三种数据的输出

1)字符串 text/plain

2)xml text/xml

3)json application/json

所以在这里不管怎么书写也不能书写text/html,因为根本不支持html

  1. 给POST请求设置编码

request.setRequestHeader(‘Content-Type’,‘application/x-www-form-urlencoded’)

如果写错了会有500错误,提示response.send()这里报错,如果这里出错就找设置编码的

2. JSON

JavaScript Object Notation

2004年诞生,2006年加入ajax技术体系,是一种轻量级的数据交换格式,成功的取代了xml,用来封装批量数据,不需要再次构建一个document对象,由于其普遍性被称之为Java的第十种常用数据类型

JSON可以同时在Java端和Js中使用

JSON其实就是一种特定格式的字符串,可以直接被打印

JSON属于第三方技术,使用时需要导入jar包

JSON存在三种封装格式,可以将数据封装为标准的JSON格式

1. Map格式

{key1:value1,key2:value2,key3:value3,keyN:valueN}

key:必须是字符串

value: 八种基本数据类型、null、String、自定义数类型、JSON

注意不能直接放置java.util.Date

//1:可以封装任意数据,封装之后呈现Map格式的JSON
			String str = "etoak";
			int i = 3;
			boolean flag = true;
			String[] strAr = {"济南","杭州","青岛"};

			JSONObject jo = new JSONObject();
			jo.put("key1",str);
			jo.put("key2",i);
			jo.put("key3",flag);
			jo.put("key4",strAr);
			//{"key1":"etoak","key2":3,"key3":true,"key4":["济南","杭州","青岛"]}
			/*
			*   这种封装方式可以封装任意数据类型,但是会导致JSON复杂度增高
			*   存在了一些不必要的数据
			* */
			System.out.println(jo);

			JSONObject jo2 = new JSONObject();
			jo2.put("boy",new Boy(1,"张三","et@etoak.com","33333"));
			//{"boy":{"phone":"33333","name":"张三","id":1,"email":"et@etoak.com"}}
			System.out.println(jo2);

			//------------------------------------------------------------------------------
			//2:专门封装Map和自定义数据类型,封装之后呈现Map类型的JSON
			Map<Integer,String> map = new HashMap<>();
			map.put(1,"Java");
			map.put(2,"Javascript");
			map.put(3,"C");
			map.put(4,"C++");
			map.put(5,"Python");
			JSONObject js = JSONObject.fromObject(map);
			//{"1":"Java","2":"Javascript","3":"C","4":"C++","5":"Python"}
			System.out.println(js);

			Boy bo = new Boy(2,"elena","et02@etoak.com","55555");
			JSONObject js2 = JSONObject.fromObject(bo);
			//{"phone":"55555","name":"elena","id":2,"email":"et02@etoak.com"}
			System.out.println(js2);
			//可以对自定义数据类型中的属性进行有选择的封装
			JsonConfig jf = new JsonConfig();
			//设置不需要封装的字段
			jf.setExcludes(new String[]{"id","phone"});
			//注意这里设置了两个参数
			JSONObject js3 = JSONObject.fromObject(bo,jf);
			//{"name":"elena","email":"et02@etoak.com"}
			System.out.println(js3);

2.数组格式

[value1,value2,value3,valueN]

value: 八种基本数据类型、null、String、自定义数类型、JSON

注意不能直接放置java.util.Date

//3:专门封装Set List 和 数组,封装之后呈现数组格式的json
JSONArray ja1 = JSONArray.fromObject(strAr);
//["济南","杭州","青岛"]
System.out.println(ja1);

List<String> list = new ArrayList<String>();
list.add("jQuery");
list.add("ExtJs");
list.add("Vue");
list.add("Angular");
list.add("React");
JSONArray ja2 = JSONArray.fromObject(list);
//["jQuery","ExtJs","Vue","Angular","React"]
System.out.println(ja2);

Set<String> set = new HashSet<String>();
set.add("山东鲁能");
set.add("上海申花");
set.add("北京国安");
set.add("上海上港");
JSONArray ja3 = JSONArray.fromObject(set);
//["北京国安","上海申花","山东鲁能","上海上港"]
System.out.println(ja3);

3.添加数据

1.直接添加

//{"key1":"etoak","key2":3,"key3":true,"key4":["济南","杭州","青岛"]}
/*
*   这种封装方式可以封装任意数据类型,但是会导致JSON复杂度增高
*   存在了一些不必要的数据
* */
JSONObject jo = new JSONObject();
jo.put("key1",str);
jo.put("key2",i);
jo.put("key3",flag);
jo.put("key4",strAr);
  1. 使用fromObject()
//2:专门封装Map和自定义数据类型,封装之后呈现Map类型的JSON
Map<Integer,String> map = new HashMap<>();
map.put(1,"Java");
map.put(2,"Javascript");
map.put(3,"C");
map.put(4,"C++");
map.put(5,"Python");
JSONObject js = JSONObject.fromObject(map);
  1. 专门封装Set 、List、和数组
List<String> list = new ArrayList<String>();
Collections.addAll(list,"Jquery","EasyUI","LayUI");
JSONArray ja = JSONArray.fromObject(list);

三种封装方式

  1. 封装任意数据类型,封装之后呈现Map格式的JSON
  2. 封装Map和自定义数据类型,封装之后呈现Map格式的JSON,并且可以针对性封装
  3. 封装数组 List 和 Set,封装之后呈现数组类型的JSON,也可以针对向的封装

强调:不能直接封装java.util.Date

4.JS解析JSON

JSON格式返回回来仅仅呗看做一个普通的字符串

从服务器返回的是一个标准的JSON格式的字符串,js并不能识别json

而仅仅将其作为字符串处理,我们现有的字符串技术无法很方便的拿取内部封装的信息
Json提供了一个转换器,可以将字符串中的键转换为js对象的属性名,将值转换为

js对象的属性值

{“etoak”:[{“name”:“山东”,“id”:1},{“name”:“湖北”,“id”:2},{“name”:“上海”,“id”:3},{“name”:“广东”,“id”:4},{“name”:“香港”,“id”:5},{“name”:“台湾”,“id”:6}]}

这个json被转换为一个js对象

转换成对象之后,可以根据

属性值 = 对象.属性名 来拿取封装的数据

//获取到JSON以后需要进行转换才能转换成JSON格式
let text = request.responseText
let json = JSON.parse(text)

3.案例

实现省份的选择

<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="UTF-8">
		<title>3)级联</title>
	</head>
	<body onload="showProvince()">
		<!--
			onchange:下拉列表框切换时激发
		-->
		请选择省份(直辖市,区划):
		<select name="province" id="province" onchange="showCity(this.value)">
			<option value="0">请选择省份</option>
		</select>

		请选择城市(区划):
		<select name="city" id="city">
			<option value="0">请选择城市</option>
		</select>

		<script>
			let request

			function create(){
			    request = new XMLHttpRequest()
			}

			function showProvince(){
			    create()
				request.open('post','show_province',true)
				request.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
				request.onreadystatechange = ()=>{
			        if(request.readyState==4){
			            if(request.status==200){
							//注意JSON格式仅仅被看做一个普通的字符串
				            let text = request.responseText
				            console.log(text)
				            //alert(text)
				            /*
				            *   从服务器返回的是一个标准的JSON格式的字符串,js并不能识别json
				            *   而仅仅将其作为字符串处理,我们现有的字符串技术无法很方便的拿取内部封装的信息
				            *   Json提供了一个转换器,可以将字符串中的键转换为js对象的属性名,将值转换为
				            *   js对象的属性值
				            *       {"etoak":[{"name":"山东","id":1},{"name":"湖北","id":2},{"name":"上海","id":3},{"name":"广东","id":4},{"name":"香港","id":5},{"name":"台湾","id":6}]}
				            *   这个json被转换为一个js对象
				            *   转换成对象之后,可以根据
				            *       属性值 = 对象.属性名 来拿取封装的数据
				            * */
				            let obj = JSON.parse(text)
				            //alert(obj)
				            //[{"name":"山东","id":1},{"name":"湖北","id":2},{"name":"上海","id":3},{"name":"广东","id":4},{"name":"香港","id":5},{"name":"台湾","id":6}]
				            let ar = obj.etoak

							//拿取省份下拉列表框
				            let dom_select = document.getElementById('province')

							for(let i = 0;i<ar.length;i++){
							    // {"name":"山东","id":1}
							    let province = ar[i]
								let id = province.id
								let name = province.name
								//将拿取的id和name放置进下拉列表框
								/*
								*   等号左边:
								*       小写o,带s,中括号内为索引值从0开始注意,这里从1开始表示
								*       默认的第0个保留
								*   等号右边j:
								*       大写O,不带s,小括号内为要添加的option的内容
								*       new Option(页面显示的值,value值)
								* */
								dom_select.options[i+1] = new Option(name,id)
							}
			            }
			        }
				}
				request.send(null)
			}

			function showCity(pid){
				create()
				request.open('post','show_city',true)
				request.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
				request.onreadystatechange = ()=>{
				    if(request.readyState==4){
				        if(request.status==200){
							let text = request.responseText
					        console.log(text)

					        let ar = JSON.parse(text)

					        //拿取city下拉列表框
					        let dom_select = document.getElementById('city')

                            //首先删除城市下拉列表框中原先存在的option
					        while(dom_select.length>1){
							    //item():括号中放置的是索引值,从0开始,这里是1表示删除第一个,保留第0个
							    dom_select.removeChild(dom_select.item(1))
					        }

					        for(let i = 0;i<ar.length;i++){

								let city = ar[i]
						        let id = city.id
						        let name = city.name

						        dom_select.options[i+1] = new Option(name,id)
					        }
				        }
				    }
				}
				request.send(`pid=${pid}`)
			}
		</script>
	</body>
</html>
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值