AJAX&JSON

原生js的AJAX应用

传统请求的缺点

我们以前的学习过程,浏览器对服务器发出的请求,都是传统的全局刷新的请求.
AJAX&JSON_第1张图片
如果我们仅仅只需要更新页面中的某一小块的内容,我们传统的全局刷新的形式,其他的部分也会随着需要更新的这一小块内容,也刷新一次.
我们现在想要的效果是,哪一块需要更新,就刷哪一块,其他的部分保持不动.这种请求,为局部刷新的请求.在浏览器上体现就是做操作以后,刷新按钮没有动
我们现在急需局部刷新的请求方式,来有效的提升用户体验.

AJAX技术应用带来的好处

ajax是一项JavaScript扩展的技术,ajax代码写在js中.
ajax技术最重要的功能是能够发出局部刷新的请求到后台servlet,servlet处理完请求后,为ajax响应一个返回值.ajax拿到返回值后,处理前端的业务逻辑.

原生js的AJAX实现步骤和同步异步操作

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ request.getContextPath() + "/";
%>





Insert title here




	
	

package com.jpg.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyServlet1 extends HttpServlet{
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		System.out.println("servlet1");
		
		String str1 = request.getParameter("str1");
		String str2 = request.getParameter("str2");
		
		/*try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}*/
		
		/*
		 * 如果当前servlet接收的请求为传统的全局刷新的请求,那么响应流就是为浏览器做html代码的响应工作
		 * 如果当前servlet接收的请求为ajax发送的局部刷新的请求,那么响应流就是为ajax技术做返回值存在的 out.print中的内容,就是为ajax返回的值
		 * 
		 */
		PrintWriter out = response.getWriter();
		out.print(str1+";"+str2);
		out.close();
		
		
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		this.doGet(request, response);
		
	}
	
}

ajax以get请求方式传递参数

和传统的get请求传参数相同,在路径后面挂参数
xmlhttp.open(“GET”, "myServlet1.do?str1=aaa&str2=bbb, true);

ajax以post请求方式传递参数

AJAX&JSON_第2张图片

使用ajax中避免浏览器缓存的方式

之所以走缓存,是因为浏览器认识了我们的请求路径,所以,想要避免缓存,让我们每一次的访问路径都不同,以挂参数的方式,但post不存在该问题,只针对get请求,因为post请求方式的路径的在地址栏不会显示
(1)随机数方式:
在这里插入图片描述
(2)时间戳方式:
在这里插入图片描述

JQuery支持的AJAX

$.ajax:最传统的基于jquery实现ajax的方式,这种方式最大的好处是使用方便,功能齐全.在实际项目开发中被普遍应用.(支持json)(用的其次)
$.get/$.post:这两种方式是基于以上$.ajax方式的简写形式,使用更加简单.在实际项目开发中使用的是最多的.但是由于应用比较简单,所以一些不常用的功能没有集成进来,所以,要有特殊需求的情况下,必须是在该方式的外部写额外的代码.(默认异步,想要修改,需要写额外的代码)(支持json)(用的最多)
$.getJSON:该方式除了能够有效的处理json数据之外,更重要的是能够读取json文件(用的不是很多)中的json内容.(用的较少)

$.ajax方式

$.ajax({
		//type:"post",	//请求方式   get/post  默认为get
		url : "myServlet2.do",	//请求路径 必要的
		async: true,	//表示同步或异步,true表示异步
		dataType : "text",	//从后台返回值的类型   text:普通文本(默认)    json:json格式的文本
		data : "str1=abc&str2=bcd",	//请求参数
		success : function(data) {	//回调函数     data:从后台接收的返回值
			
			$("#msg").html(data);
			
		}
});

上述的dataType,如果后台设置相应的类型为:response.setContentType(“text/json;charset=utf-8”);则dataType可省略

$.get方式和$.post方式

默认异步,若需修改,在get或post外面修改
这种形式顺序不能乱,第一位是请求的路径
第二位是请求的参数
第三位是回调函数
第四位是从后台的返回值的类型
如果没有请求参数,直接删除即可,这样,回调函数排在第二位
$.get(
	   "myServlet1.do", 
	    "username=zs&password=123", //以传统方式传参数
	    function(data) {
	    	$("#msg").html(data);
		},
		"text"
	);

JSON

语法

{“key1”:”value1”,”key2”:”value2”}
{key1:”value1”,key2:”value2”}
[{},{},{}] 集合
{“id”:”A0001”,”name”:”zs”,”age”:23}
key如果要加双引号,剩下的key都加,要不加,都不加

ajax以json格式传递参数

$.get(
	   "myServlet1.do", 
	    {"username":username,"password":password}, //以json格式传参数
	    function(data) {
	    	$("#msg").html(data);
		},
		"text"
	);

ajax以json格式接收返回值(json的拼接)

拼接的步骤:
(1).写json模板
(2).将json模板粘贴到空串中
(3).将双引号转义
(4).为?赋值
1.接收单个值
2.接收多个值

//传递多个值
//{"str1":"aaa","str2":bbb}
String str = "{\"str1\":\"aaa\",\"str2\":\"bbb\"}";

3.接收单个对象

//接受单个对象
//{"id":"?", "name":"?", "age":?}

String str = "{\"id\":\""+s.getId()+"\", \"name\":\""
+s.getName()+"\", \"age\":"+s.getAge()+"}";
$.post(
	"myServlet2.do",
	function(data) {
		alert(data.id);
	},
	"json"
)

4.接收多个对象

//接受多个对象
//{"id":"?", "name":"?", "age":?}
//{"s1":{"id":"?", "name":"?", "age":?}, "s2":{"id":"?", "name":"?", "age":?}}

String str = "{\"s1\":{\"id\":\""+s1.getId()+"\", \"name\":\""
+s1.getName()+"\", \"age\":"+s1.getAge()+"}, \"s2\":{\"id\":\""
+s2.getId()+"\", \"name\":\""+s2.getName()+"\", \"age\":"+s2.getAge()+"}}";
$.post(
		"myServlet3.do",
		function(data) {
			alert(data.s2.id);
		},
		"json"
	)

5.接收集合

public class MyServlet4 extends HttpServlet {
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		PrintWriter out = response.getWriter();
		
		Student s1 = new Student("A0001", "zs", 23);
		Student s2 = new Student("A0002", "ls", 24);
		Student s3 = new Student("A0003", "ww", 25);
		Student s4 = new Student("A0004", "zl", 26);
		Student s5 = new Student("A0005", "sq", 27);
		
		List<Student> sList = new ArrayList<Student>();
		
		sList.add(s1);
		sList.add(s2);
		sList.add(s3);
		sList.add(s4);
		sList.add(s5);
		
		//接受集合
		//{"id":"?", "name":"?", "age":?}
		//{"sList":[{"id":"?", "name":"?", "age":?},{},{}]}
		
		//我们需要使用循环的形式来拼接
		StringBuffer buf = new StringBuffer();
		buf.append("{\"sList\":[");
		//使用普通for循环是因为我们需要使用到i,来拼接逗号
		for(int i = 0; i < sList.size(); i++) {
			Student s = sList.get(i);
			//因为大量的+拼接,相当于String拼接,所以需要分开来append
			//buf.append("{\"id\":\""+s.getId()+"\", \"name\":\""+s.getName()+"\", \"age\":"+s.getAge()+"}");
			buf.append("{\"id\":\"");
			buf.append(s.getId());
			buf.append("\", \"name\":\"");
			buf.append(s.getName());
			buf.append("\", \"age\":");
			buf.append(s.getAge());
			buf.append("}");
			if (i < sList.size() - 1) {
				buf.append(",");
			}
		}
		
		buf.append("]}");
		
		out.print(buf.toString());
		out.close();
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}

}

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + 	request.getServerPort() + request.getContextPath() + "/";
%>

<html>
<head>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js">script>
<script type="text/javascript">
	$(function(){
		$("#djBtn").click(function(){
			//当每一次点击的时候,将原先展示的数据设置为空
			$("#tbody").html("");
			$.post(
				"myServlet4.do",
				function(data) {
					/*
						数据我们已经拿到了,我们以前的方式是拿到数据以后,将数据铺到table中,
						我们以前使用的el和jstl,因为是全局刷新的方式,现在我们是以AJAX局部
						刷新请求的方式拿到的数据,我们是使用的动态拼接table的方式,来将数据铺到table
					*/
					var i = 1;
					//$(data.sList)拿到了json数组,将其转换成jQuery对象
					$(data.sList).each(function(){
						//每一个json对象使用this表示
						$("#tbody").append(""+(i++)
								+""+this.id+""+this.name
								+""+this.age+"删除||修改");
					})
				},
				"json"
			)
			
		});
	})
	
script>
head>
<body>
	<button id="djBtn">点击button><br>
	<table border="1" align="center" width="70%" cellpadding="6px" cellspacing="0">
		<thead>
			<tr>
				<td>序号td>
				<td>编号td>
				<td>姓名td>
				<td>年龄td>
				<td>操作td>
			tr>
		thead>
		
		<tbody id="tbody">
		
		tbody>
	table>

body>
html>

实战: 省市联动

需求:为点击的时候,两个下拉框中没有内容,当点击后,第一个下拉框显示省份,第二个框只要在选中省份后,才会显示对应的城市
在这里插入图片描述
省份表和城市表,一对多的关系,一个省份里面有多个城市,一个城市只能属于一个省份.
省份:一
城市:多
我们使用外键来描述表与表之间的关系
在谁的一方建立关系?(在哪张表中建立外键?)
永远是在多的一方建立关系(在多的一方建立外键)
省份表 tbl_province
id name
1 辽宁
2 吉林
3 黑龙江

城市表 tbl_city
id name pid
1 沈阳 1
2 大连 1
3 长春 2

如果外键换成pname可以吗?只记录下,该城市所属于的省份,这样不用多表联查,一张表搞定?也可以,但是存在缺点,第一:获取不到省份的其他信息,只能获取到省份名称,第二:数据得不到及时的更新,如果省份的名称发生了变化,那么城市表中的省份的字段的不到及时的更新,所以还是用pid作为外键合适
如果数据量过大,并且查询城市所属的省份很频繁,我们可以给城市表添加冗余字段pname,这样用一张表搞定,提高效率
关于建立外键有两种形式,一种是不直接建立外键,但是关系是外键关系,还有一种是真正的建立起外键(删除的麻烦),在实际项目开发中,一般采用第一种

$("#djBtn").click(function(){
			//当每一次点击的时候,将原先展示的数据设置为空
			$("#pid").html("");
			$.post(
				"province/list.do",
				function(data) {
					
					$(data.pList).each(function(){
						$("#pid").append("this.id+">"+this.name+"")
					});
				},
				"json"
			)
			
		});
		
		//判断下拉框的值是否变化,是change事件
		$("#pid").change(function(){
			
			$("#cid").html("");
			//选中option后会将option的value值赋值给select的value
			var pid = $("#pid").val();
			
			$.post(
					"city/list.do",
					"pid="+pid,
					function(data) {
						$(data.cList).each(function(){
							$("#cid").append("this.id+">"+this.name+"")
						});
					},
					"json"
				)
		});

转发形式向AJAX传返回值

如果是以request域+转发来向AJAX返回值,那么必须以json的形式来传数据,这样不会受到换行的影响,比如:

ajax请求传递:
$("#djBtn").click(function(){
	$.post(
		"myServlet1.do",
		function(data){
		//先弹出data,如果后台响应回的值等于aaa则弹出success
		//在该程序中,是使用request+转发来给ajax返回值,因为是以文本的形式传数据,
		//所以不会忽略换行的处理,最后返回的ajax的数据是两个换行+aaa,所以不会弹出success
		//在转发的目标
			alert(data);
			if(data=="aaa"){
				alert("success");
			}
		}
		
	)
})
servlet处理:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("进入myServlet1"); 
		String str1 = "aaa";
		request.setAttribute("data",str1);
		//如果写成以下json传输数据的格式,则会忽略换行,在该例子中会弹出success
		//String str1 = "{\"str1\":\"aaa\"}";
		//request.setAttribute("data",str1);
		request.getRequestDispatcher("/data.jsp").forward(request, response);
	}
转发的指定页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
${data}

$.getJSON的使用

我们以前都是发送请求到后台,从后台取数据,这种方式直接从json文件中取数据
这种方式中,从后台的返回值类型不用写,就是json

//为点击按钮绑定事件
		$("#djBtn").click(function() {
			
			$.getJSON(
				"js/demo.json", 	//表示要读取的json文件的路径
				function(data) {
					alert(data.name);
				}
			)

		})

AJAX&JSON_第3张图片

ajax的跨域操作

什么是跨域操作

对于我们的ajax操作,都是从后台去取ajax的返回值.
我们都是从我们自己的项目的后台去取返回值
以前的形式
AJAX&JSON_第4张图片
如果将路径加全
AJAX&JSON_第5张图片
以上的访问路径,说明发出的ajax请求,是从我们自己的服务器的项目中的后台去取数据.
根据以上访问路径,其中的协议 ip 端口号,这3个条件,改变其中一种,就是跨域操作.
跨域操作,就是从别人家取数据

跨域操作案例

天气预报,腾讯qq的天气采用的是中国天气网的数据

实际项目开发中跨域的应用

以前
util包
domain包
servlet包

以后
util项目
domain项目
servlet项目

只是举例,以后并不这样分层
将三个项目分别放到三个服务器,浏览器首先访问servlet服务器,因为servlet需要谁用到domain项目和util项目中的内容,只能通过跨域进行访问

你可能感兴趣的:(Web)