什么是AJAX【Asynchronous异步的JS和XML】,工作原理与特点
(1)什么是同步:
请求1->响应1->请求2->响应2->
Web1.0时代
(2)什么是异步:
请求1->请求2->请求3->响应1->响应2->响应3->
请求1->响应1->请求2->请求3->响应2->响应3->
Web2.0时代
项目中:Web1.0为主(整个浏览器刷新),Web2.0为辅(浏览器局部刷新)
(3)什么是AJAX
客户端(特指PC浏览器)与服务器,可以在【不必刷新整个浏览器】的情况下,与服务器进行异步通讯的技术
即,AJAX是一个【局部刷新】的【异步】通讯技术
AJAX不是全新的语言,是2005年Google公司推出的一种全新【编程模式】,不是新的编程语言
创建Ajax
AJAX开发步骤
步一:创建AJAX异步对象,例如:createAJAX()
步二:准备发送异步请求,例如:ajax.open(method,url)
步三:如果是POST请求的话,一定要设置AJAX请求头,例如:ajax.setRequestHeader()
如果是GET请求的话,无需设置设置AJAX请求头
步四:真正发送请求体中的数据到服务器,例如:ajax.send()
步五:AJAX不断的监听服务端响应的状态变化,例如:ajax.onreadystatechange,后面写一个无名处理函数
步六:在无名处理函数中,获取AJAX的数据后,按照DOM规则,用JS语言来操作Web页面
AJAX适合用在什么地方
AJAX【适合】不用来传递大量数据,而只用来【传递少量数据】,在用户的【体验】上,【更加人性化】
AJAX是一个和服务器无关的技术,即服务器可使用:JavaEE,.NET,PHP,。。。这些技术都可
AJAX只管向服务器发送请求,同时只管接收服务器的HTML或XML或JSON载体响应
服务端不能使用转发或重定向到web页面,因为这样会起浏览器全面刷新
即只能以流的方式响应给浏览器
AJAX应用
(1)无需刷新整个Web页面显示服务器响应的当前时间
步骤一:创建一个显示时间的jsp页面。
当前时间:<span></span><br/>
<input type="button" value="异步方式提交"/>
<script type="text/javascript">
document.getElementsByTagName("input")[0].onclick = function(){ //定位button按钮,同时添加单击事件
//NO1)创建AJAX异步对象(每个浏览器内置的,无需第三方jar包)
var ajax = createAJAX();//0
//NO2)AJAX异步对象准备发送请求
var url = "${pageContext.request.contextPath}/TimeServletAjax?id="+new Date().getTime();
var method = "GET";
ajax.open(method,url);//1
//NO3)AJAX异步对象真正发送请求体的数据到服务器,如果请求体无数据的话,用null表示
var content = null;
ajax.send(content);//2
//----------------------------------------等待
//NO4)AJAX异步对象不断监听服务端状态的变化,只有状态码变化了,方可触发函数
//0-1-2-3-4,这些是可以触发函数的
//4-4-4-4-4,这些是不可以触发函数的
//以下这个函数是服务器来触发的,不是程序员触发的,这和onclick是不一样的
ajax.onreadystatechange = function(){
if(ajax.readyState == 4){ //如果AJAX状态码为4
if(ajax.status == 200){ //如果服务器响应码是200
//NO5)从AJAX异步对象中获取服务器响应的结果
var str = ajax.responseText;
//NO6)按照DOM规则,将结果动态添加到web页面指向的标签中
document.getElementsByTagName("span")[0].innerHTML = str;
}
}
}
}
</script>
步骤二:.创建一个TimeServletAjax 的servlet
public class TimeServletAjax extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = sdf.format(new Date());
//注意:在Web2.0时代,即异步方式下,不能用转发或重定向
//因为:转发或重定向会引起浏览器全部刷新,而不是局部刷新
//所以得用以输出流的方式将服务器的结果输出到浏览器
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.write(str);
pw.flush();
pw.close();
}
}
运行一下~
(2)基于HTML,以GET或POST方式,检查注册用户名是否在数据库中已存在
(这里的数据库是我们自己设置的一个名字,没有实际去访问数据库,只是为了简单测试效果)
步骤一:建立一个简单的注册界面
<body>
<form action="01_time.jsp" method="GET">
<table border="2" align="left">
<tr>
<th>用户名</th>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<th>密码</th>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td colspan="2" align="center">
<input id="ID" type="button" name="submit" value="提交" style="width:111px"/>
</td>
</tr>
</table>
</form>
<span></span>
<script type="text/javascript">
$(":button").click(function(){
var username=$(":text").val();
var password=$(":password").val(); //加上每次新的时间使服务器重新启动,而不是在缓存中拿值
var url="${pageContext.request.contextPath}/servlet/UserServlet?time="+new Date().getTime();
/* var sendData={
"username" :username,
"password" :password //使用js键值对方式编写
}; */
var sendData=$("form").serialize(); //序列化的值作为url的参数传给ajax()
$.post(url,sendData,function(backData){ //使用了post函数
var backDate=backDate; //这里的返回函数中放置的是图标的代表值
var $img=$("<img src='"+backData+"'width='14px' height='14px'/>");
$("span").text(""); //将页面span置空,放入图标
$("span").append($img);
})
});
</script>
</body>
步骤二:建立一个处理业务的servlet
public class UserServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String username=request.getParameter("username");
String password=request.getParameter("password");
String tip="images/MsgSent.gif";
if(username.equals("李四")&&password.equals("123")){
tip="images/MsgError.gif";
}
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw=response.getWriter();
pw.write(tip);
pw.flush();
pw.close();
}
}
运行一下~
(3)基于xml,以post方式完成省份城市的二级联动
步骤一:建好一个用来联动的jsp界面
<body>
<select id="province">
<option>请选择省份</option>
<option>湖南</option>
<option>广东</option>
</select>
<select id="city">
<option>请选择城市</option>
</select>
<script type="text/javascript">
debugger
$("#province").change(function(){
//清空城市下拉框的内容(除第一项)
$("#city option:gt(0)").remove();
var province=$("#province option:selected").text();
if("请选择省份"!=province){
$.ajax({ //这里使用了ajax函数
type : "POST",
url : "${pageContext.request.contextPath}/struts2/findCityByProvinceRequest",
data : {"province":province},
success : function(backdata,textStatus,ajax){
alert(backdata!=null?"收到":"未收到");
// alert(ajax.responseText);
//解析json文本
var array=backdata.setCity;
var size=array.length;
for(var i=0;i<size;i++){
var city=array[i];
var $option=$("<option>"+city+"</option>");
$("#city").append($option);
}
}
});
}
});
</script>
</body>
步骤二:创建一个处理业务逻辑的action ProvinceCityAction
public class ProvinceCityAction extends ActionSupport{
private String province;
public void setProvince(String province) {
this.province = province;
System.out.println("注入"+province);
}
//根据省份查询城市
public String findCityByProvince() throws Exception {
setCity=new LinkedHashSet<String>();
if("湖南".equals(province)){
setCity.add("长沙");
setCity.add("株洲");
}else if("广东".equals(province)){
setCity.add("广州");
setCity.add("佛山");
setCity.add("中山");
}
return SUCCESS;
}
private Set<String> setCity;
public Set<String> getSetCity() {
return setCity;
}
}
步骤三:在xml文件中对action进行配置
<package name="myPackage" extends="json-default" namespace="/"> //注意:json-default可以实现json和struts的完美结合
<!-- 根据省份查询城市 -->
<action name="findCityByProvinceRequest"
class="provincecity.ProvinceCityAction"
method="findCityByProvince">
<result name="success" type="json"> //type="json"json plugin就会自动将指定的内容转化成json格式
</result>
</action>
</package>
方式一:包名直接继承json-default(如上)
方式二:在包中直接加上<result-types>的定义
<result-types>
<result-type name="json" class="org.apache.struts2.json.JSONResult"/>
</result-types>
以及web.xml中的核心过滤器的配置
<filter>
<filter-name>StrutsPrepareAndExecuteFilter</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>StrutsPrepareAndExecuteFilter</filter-name>
<url-pattern>/struts2/*</url-pattern>
</filter-mapping>
运行一下~