ajax学习记录【1】【介绍、jq实现、数据传输】


1.ajax介绍

Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式、快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

好处:提供类似C/S的交互效果,操作更方便。

1.1.与传统Web的区别:

(1)传统Web:提交表单发送请求
          Ajax:异步引擎对象发送请求
(2)传统Web:响应内容是一整个界面
          Ajax:响应内容只是需要的数据
(3)传统Web:等待服务器响应完成后加载
          Ajax:无需等待

1.2.基本用法

在这里插入图片描述

1.2.1.JavaScript对象XMLHttpRequest是整个Ajax技术的核心,主要方法:

(1)open(method.URL,async):
         method:请求方式(POST&GET[默认])
         URL:请求地址
         async:是否异步(true[默认]&false)
(2)send(content):
         content:请求参数(只有post请求才能通过send()发送参数)
(3)setRequestHeader(header,value):
         设置请求头信息

同步请求:发送请求后,整个页面不可操作。在服务端响应之前,浏览器处于阻塞状态,必须等待服务端的响应。此时不能进行交互操作。
异步请求:传数据在服务端执行,但同时前端也在接着执行后续代码。所以不能获取数据太早,否则后端数据还没传过来,前端得不到数据,就显示不出来。

1.2.2.常用属性:
1.2.2.1.readyState:表示XMLHttpRequest对象的状态:

         0:已创建,还没初始化;
         1:XMLHttpRequest对象开始发送请求;(open)
         2:XMLHttpRequest对象请求发送完成;(send)
         3:XMLHttpRequest对象开始读取响应,还没结束;
         4:XMLHttpRequest对象读取响应结束;

1.2.2.2.onreadystatechange:事件属性

指定回调函数,当readyState属性改变时触发,即readyState的值每一次变化时都会触发。必须在执行send方法前指定

function login(){
			//创建对象
			var xhr=new XMLHttpRequest();
			//指定事件回调函数
			xhr.onreadystatechange=function(){
				if(xhr.readyState==4){//当数据传回来后执行
					var data=xhr.responseText;
					alert(data);
				}
			}
			//初始化连接
			xhr.open("get","simple",true);
			//发送请求
			xhr.send(null);	
		}

注:当后台无法响应时,该代码最后仍会有弹框响应。说明对象状态仍然在改变,所以判断不能只看readyState的状态,所以还要接着判断:

1.2.2.3.status:表示HTTP请求响应状态

         200:服务器响应正常;
         400:无法找到请求的资源;
         403:没有访问权限;
         404:访问的资源不存在;
         500:服务器内部错误;
故改为:

function login(){
			//创建对象
			var xhr=new XMLHttpRequest();
			//指定事件回调函数
			xhr.onreadystatechange=function(){
				if(xhr.readyState==4&&xhr.status==200){//当数据传回来后执行
					var data=xhr.responseText;
					alert(data);
				}
			}
			//初始化连接
			xhr.open("get","simple",true);
			//发送请求
			xhr.send(null);	
		}

注:if中两个判断的顺序不能颠倒

1.2.2.4.响应内容

         responseText:获得响应的文本内容;
         responseXML:获得响应的XML文档对象Document

1.3.使用Ajax校验用户名(参数传递问题)

         例如注册时,查询数据库后提示“用户名已存在”:
         控件:

	<form role="form" class="form-horizontal">
		<div class="form-group">
	   	<label class="control-label col-md-2">用户名:</label>
		<div class="col-md-4">
			<input type="text" id="username" class="form-control" onBlur="login(this.value);" placeholder="请输入用户名">
			<span id="log"></span>
		</div>
		</div>
	</form>	
1.3.1.通过get方式发送请求
//初始化连接
xhr.open("get","checkUsername?username"+username,true);
//发送请求
xhr.send(null);	

此时不能使用send来发送,服务端接收不到,如以下代码(不可实现):

//初始化连接
xhr.open("get","checkUsername",true);
//发送请求
xhr.send("username"+username);	
1.3.2.通过post方式发送请求

请求头不可缺少,必须设置在send前面
若将参数设置在url中,则效果与get方式无异

//初始化连接
xhr.open("post","checkUsername",true);
//设置请求头(不可缺少)
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");//可通过设置请求头解决中文乱码问题
//发送请求
xhr.send("username"+username+"&password="+pwd);	(多个数据的写法)
1.3.3.get和post的区别

get:
(1)地址栏会显示数据
(2)传递数据大小受地址栏长度限制
(3)字符集会被自动转换为ISO-8859-1,中文会有乱码,一般需要在服务器端进行解码:
方法一(服务器解码):

String username=req.getParamenter("username");
username=new String(username.getBytes(iso-88596-1),"utf-8");

req.setCharacterEncoding("utf-8");
String username=req.getParamenter("username");

方法二:使用过滤器Filter
方法三:直接修改Tomcat配置文件:server.xml,设置URIEncoding=“utf-8”(推荐方式)

post:
(1)地址栏只会显示地址,数据通过请求头发送
(2)理论上数据大小无限制
(3)文件上传必须使用post方式
(4)相比较而言,post比get更安全,但两者都是以明文形式传输,get可在地址栏中看到数据,post可通过打开控制台看到请求头传递的数据
(4)可通过请求头设置字符集类型,服务器端会自动识别,解决乱码:
方法一(客户端设置请求头):

xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");

方法二(服务器设置字符集):

req.setCharacterEncoding("utf-8");

方法三:使用过滤器Filter (推荐方式)

2.jQuery实现

2.1.使用$.ajax()发送Ajax请求

         加载远程数据,最底层Ajax实现,不要忘了逗号和最后中括号后的分号

		function login(){
			var username=$("#username").val();
			var pwd=$("#pwd").val();
			$.ajax({
				type:"post",//请求方式,默认是get
				url:"login",//url
				async:true,//异步同步,默认异步true
				data:{
					"username":username,
				    "pwd":pwd
				},//JSON格式
				dataType:"text",//服务器端响应的数据类型,默认text
				timeout: 1000, //超时时间设置,单位毫秒
				success:function(data){ //请求成功的回调函数,data为从服务端成功获得的返回值
    			alert("成功");
  				},
				error:function(){//请求失败
					$("#log").html("Ajax请求失败");
				},
				complete:function(XMLHttpRequest,status){ //请求完成后最终执行参数
					if(status=='timeout'){//超时,status还有success,error等值的情况
						alert("超时");
					}
				},
				beforeSend:function(){//中途执行
					$("#log").html("正在登陆中");
				}  
			});
		}

2.2.使用$.get()发送Ajax请求

         get请求从服务器加载数据$get(url,data,success(resp,status,xhr),dataType)

		$.get(
			"login",//url
			{
				"username":username,
				"pwd":pwd
			},//data
			function(data){ //success
    			alert("成功");
  			},
			"text"//dataType,可省略
		);

2.3.使用$.post()发送Ajax请求

         post请求向服务器传送数据比$get(url,data,success(resp,status,xhr),dataType)

		$.post(
			"login",//url
			{
				"username":username,
				"pwd":pwd
			},//data
			function(data){ //success
    			alert("成功");
  		},
			"text"//dataType,可省略
		);

2.4.使用$.getJSON()发送Ajax请求

         从服务器加载JSON数据到客户端$getJSON(url,data,success(result,status,xhr));,默认使用get发送请求,且不能改成post

		$.getJSON(
			"login",//url
			{
				"username":$("#username").val(),
				"pwd":$("#pwd").val()
			},//data
			function(data){ //success
    			alert("成功");
  			}
		);
		$.getJSON(
			"userlist.json"//url
			//data省略
			function(data){//success
				//循环userlist.json返回的JSON数组
				$.each(data,function(inndex,user){
					$("<p>").text(user.id+"  "+user.username).appendTo("#username");
				});
			}
		);

其他:$(selector).append(content)$(content).appendTo(selector)作用相同,注意内容填写顺序

2.5.使用$(选择器).load()发送Ajax请求

         从服务器加载数据,并把返回的数据放置到指定元素中,最简单的方法$(选择器).load(url,data,function(result,status,xhr));
服务器端成功返回对象后,可将数据隐式添加到调用的jQuery对象中,相当于$().html();
course.html的全部内容(没有<html>、<body>等):

<ul>
	<li>这是第1门课</li>
	<li>这是第2门课</li>
	<li>这是第3门课</li>
	<li>这是第4门课</li>
	<li>这是第5门课</li>
</ul>

本文件中的load调用,将文件内容都添加到本文件的id为log的板块

$("#log").load("course.html"function(){
	alert("成功");
});

2.6.补充:序列化表单元素$(selector).serialize()

         可将表单中有name属性的元素进行序列化,生成标准URL编码文本字符串,直接用于Ajax请求。
注意,必须在 表单(form) 中,文本框等需要使用 name 属性,不能使用id属性

<!doctype html>
<html>
	<head>
	<meta charset="utf-8">
	<title>。。。</title>
	<link href="../bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css">
	<script src="../jquery-3.4.1/jquery-3.4.1.js"></script>
	<script src="../bootstrap/js/bootstrap.min.js"></script>
	<script>
		function login(){
			var params=$("#login").serialize();
			console.log(params);
		}
	</script>
	</head>
	<body>
    <form role="form" class="form-inline" id="login">
      <div class="form-group">
        <input type="text" name="username" class="form-control" placeholder="请输入用户名">
      </div>
      <div class="form-group">
        <input type="text" name="pwd" class="form-control" placeholder="请输入密码">
        <div class="form-group">
          <div id="log" class="btn btn-danger" onclick="login()">点我提交</div>
        </div>
      </div>
    </form>
</body>
</html>

html界面:
在这里插入图片描述
输入信息后,查看控制台:
在这里插入图片描述

2.7.补充:EL表达式

         EL(Expression Language) 是为了使JSP写起来更加简单。表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让Jsp的代码更加简化。
例如,< %=request. getParameter(“username”)% > 等价于 ${ param. username }

2.7.1.EL语法
在JSP中访问模型对象是通过EL表达式的语法来表达。
所有EL表达式的格式都是以“${}”表示。
例如,${ userinfo}代表获取变量userinfo的值。
当EL表达式中的变量不给定范围时,则默认在page范围查找,
然后依次在request、session、application范围查找。
也可以用范围作为前缀表示属于哪个范围的变量,
例如:${ pageScope. userinfo}表示访问page范围中的userinfo变量。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
来源:https://baike.baidu.com/item/EL%E8%A1%A8%E8%BE%BE%E5%BC%8F/1190845?fr=aladdin

2.7.2.设置EL

注意 <%@ page isELIgnored=“true” %> 表示是否禁用EL语言,TRUE表示禁止.FALSE表示不禁止.JSP2.0中默认的启用EL语言。
全局禁用EL表达式,在web.xml中进行如下配置:

<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<el-ignored>true</el-ignored>
</jsp-property-group>
</jsp-config>
2.7.3.EL总结

EL表达式不能出现在Java代码块、表达式块等JSP动态代码部分
EL只能从四大域属性空间中获取数据(pageContext、request、session、application)
EL不会抛出空指针异常,只会不显示
EL不会抛出数组越界异常,只会不显示
EL不具有对字符串进行处理的能力(可以使用JSTL的EL或者自定义EL函数)
来源:https://blog.csdn.net/w_linux/article/details/79850223

3.返回数据

案例:课程选择

服务器端只能用三种格式返回数据:text、JSON、XML
HTML:

	<select name="select" id="type" class="form-control">
		<option value="0">请选择</option>
	</select>
3.1.text数据传输

JS:

$("#type").get("classlist",//url
					  function(data){
			var classnames=data.split(";");//假设从服务器获得一长串字符串,每一组数据内容用“;”分隔,在服务层要去除最后一个“;”,组内不同数据用“,”隔开
			for(var i=0; i < classnames.length ; i++){
				var classname=classnames[i].split(",");
				var item=document.createElement("option");
				item.setAttribute("value",classname[0]);
				$("#type").append(item);
			}
		});

在servlet中,有:

response.setContentType("text/plain;charset=utf8");//设置返回类型为text,且为utf-8
3.2.XML数据传输

servlet:

response.setContentType("text/xml;charset=utf8");//设置返回类型为xml,且为utf-8

且需要对dom4j的document对象进行转化,不能直接用。

ByteArrayOutputStream baos=new ByteArrayOutputStream();
XMLWriter xw=new XMLWriter(baos,format);
xw.write(document);//此document即从xml文件通过dom4j获得的内容
   //此时baos中即为xml文件内容
PrintWriter out = response.getWriter();
out.write(baos);

JS:

$("#type").get("classlist",//url
			function(data){//data就是一个XML文件
				var a=data.getElementsByTagName("Course");
				for(var i=0;i<a.length;i++){
					var e=a[i].firstChild.nadeValue;
					var c=$("#type").createElement("option");
					c.append(e);
					c.setAttribute("value",e);
					$("#type").append(c);
				}
			},"xml");
3.3.自动补全(用户搜索时显示自动提示,autocomplete)

HTML:

<input type="text" name="username" id="username" class="form-control" placeholder="请输入用户名">

注意:使用autocomplete需要引入:

<script src="../jquery-ui-1.12.1.custom/jquery-ui.min.js"></script>
<link href="../jquery-ui-1.12.1.custom/jquery-ui.min.css">

JS:

		$(function(){
			$("#username").autocomplete({
				minLength:2,//设置至少输入两个字时出现提示
				source:function(req,res){
					//用函数从服务器拿到可以显示的信息
					var keyword=req.term;
					$.get("","name="+keyword,function(data){
						var name=data.split(",");
						res(name);//显示提示(可显示列表,但样式还需要设置)
					};
					
				},
			});
		});

:Function(request, response):一个回调函数,提供最大的灵活性,可用于连接任何数据源到 Autocomplete。通过request.term获得输入的值,response来呈现数据。
request对象只有一个term属性,对应用户输入的文本
response是一个函数,在开发人员自行处理并获取数据后,将JSON数据交给该函数处理,以便于autocomplete根据数据显示列表

3.4.JSON数据传输
3.4.1.获取JSON字符串,自己解析(eval、$.parseJSON、JSON.parse)

servlet:

out.print("{'id':1001,'name':jack,'age':20}");//JSON.parse()无法解析里面是单引号的,所以这样写不能用以下方法(2),方法(3)同理,也不能解析不规范的JSON文本

//规范的:使用\转义
out.print("{\"id\":1001,\"name\":jack,\"age\":20}");

JS:

		function getuser(){
			$.ajax({
				url:"",
				dataType:"text",//服务器返回的是JSON格式的字符串
				success:function(data){
					//方法(1)使用原生的eval()解析
					var obj=eval("("+data+")");
					//方法(2)使用JSON.parse()解析,ES5中新增
					var obj=JSON.parse(data);
					//方法(3)使用$.parseJSON()解析,ES5中新增
					var obj=$.parseJSON(data);
					
					//此处index是属性名,输出例如:id=1001
					for(index in obj){
						console.log(index+"="+obj[index]);
					}
				}
			});
		}

eval() 使用的是JS解析器,可解析JSON文本,生成JS对象,必须把文本包围在括号中,才能避免语法错误,但如果是JSON数组,则不需要加括号

3.4.2.直接获取JSON对象,自动解析

servlet:

//规范的:使用\转义
out.print("{\"id\":1001,\"name\":jack,\"age\":20}");

JS:将dataType改为json即可

function getuser(){
			$.ajax({
				url:"",
				dataType:"json",//服务器返回的是JSON类型的数据
				success:function(data){
				}
			});
		}
3.4.3.使用第三方插件:json.jar(需添加jar包)【好用方便】
3.4.3.1.单个对象或Map集合使用JSONObject

srevlet:

//例如有数据User user=new User(1234,"aa","男",25);
JSONObject obj=new JSONObject(user);
String str=obj.toString();//此时str即为自动拼接好的JSON字符串,无需手动拼接

此时str即为自动拼接好的JSON字符串,无需手动拼接
但必须保证有user值,比如从数据库中没有取到东西,则会报空指针错误,所以,需要对user是否为null进行if判断:

String str="";
if(user!=null){
	JSONObject obj=new JSONObject(user);
	String str=obj.toString();//此时str即为自动拼接好的JSON字符串,无需手动拼接
}
3.4.3.2.多个对象(List集合或数组)使用JSONArray

srevlet:

/*例如有数据:
	List<User> users=new ArrayList<User>();
	users.add(new User(1234,"aa","男",25));
	users.add(new User(1235,"bb","女",28));
	users.add(new User(1236,"cc","男",25));
*/
JSONArray obj=new JSONArray(user);
String str=obj.toString();//此时str即为自动拼接好的JSON字符串,无需手动拼接

此时users可以为null,不会报错

学习进度:3/5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值