Ajax【介绍、入门、解决Ajax中文、跨域、缓存】

什么是Ajax

Ajax(Asynchronous JavaScript and XML) 异步JavaScript和XML

Ajax实际上是下面这几种技术的融合:

  • (1)XHTML和CSS的基于标准的表示技术
  • (2)DOM进行动态显示和交互
  • (3)XML和XSLT进行数据交换和处理
  • (4)XMLHttpRequest进行异步数据检索
  • (5)Javascript将以上技术融合在一起

客户端与服务器,可以在【不必刷新整个浏览器】的情况下,与服务器进行异步通讯的技术

为什么我们需要Ajax?

在我们之前的开发,每当用户向服务器发送请求,哪怕只是需要更新一点点的局部内容,服务器都会将整个页面进行刷新。

  • 性能会有所降低(一点内容,刷新整个页面!)
  • 用户的操作页面会中断(整个页面被刷新了)

Ajax就是能够做到局部刷新!

这里写图片描述


XMLHttpRequest

XMLHttpRequest对象是Ajax中最重要的一个对象。使用Ajax更多的是编写客户端代码,而不是服务端的代码。

XMLHttpRequest 工作原理

传统的web前端与后端的交互中,浏览器直接访问Tomcat的Servlet来获取数据。Servlet通过转发把数据发送给浏览器。

当我们使用AJAX之后,浏览器是先把请求发送到XMLHttpRequest异步对象之中,异步对象对请求进行封装,然后再与发送给服务器。服务器并不是以转发的方式响应,而是以流的方式把数据返回给浏览器

XMLHttpRequest异步对象会不停监听服务器状态的变化,得到服务器返回的数据,就写到浏览器上【因为不是转发的方式,所以是无刷新就能够获取服务器端的数据】

这里写图片描述


创建XMLHttpRequest对象

要创建XMLHttpRequest对象是要分两种情况考虑的:

  • 在IE6以下的版本
  • 在IE6以上的版本以及其他内核的浏览器(Mozilla)等
  1.  
     
  2.  
    <script type="text/javascript">
  3.  
     
  4.  
    var httpRequest;
  5.  
     
  6.  
    if(window.XMLHttpRequest) {
  7.  
     
  8.  
    //在IE6以上的版本以及其他内核的浏览器(Mozilla)等
  9.  
    httpRequest = new XMLHttpRequest();
  10.  
    } else if(window.ActiveXObject) {
  11.  
     
  12.  
    //在IE6以下的版本
  13.  
    httpRequest = new ActiveXObject();
  14.  
    }
  15.  
     
  16.  
     
  17.  
    </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

了解XMLHttpRequest对象的属性和方法

方法

  • open()(String method,String url,boolean asynch,String username,String password)
  • send(content)
  • setRequestHeader(String header,String value)
  • getAllResponseHeaders()
  • getResponseHeader(String header)
  • abort()

常用的方法就是黑色粗体的前三个

  • open():该方法创建http请求
    • 第一个参数是指定提交方式(post、get)
    • 第二个参数是指定要提交的地址是哪
    • 第三个参数是指定是异步还是同步(true表示异步,false表示同步)
    • 第四和第五参数在http认证的时候会用到。是可选的
  • setRequestHeader(String header,String value):设置消息头(使用post方式才会使用到,get方法并不需要调用该方法)
    • xmlhttp.setRequestHeader(“Content-type”,”application/x-www-form-urlencoded”);
  • send(content):发送请求给服务器
    • 如果是get方式,并不需要填写参数,或填写null
    • 如果是post方式,把要提交的参数写上去

属性

  • onreadystatechange:请求状态改变的事件触发器(readyState变化时会调用此方法),一般用于指定回调函数
  • readyState:请求状态readyState一改变,回调函数被调用,它有5个状态
    • 0:未初始化
    • 1:open方法成功调用以后
    • 2:服务器已经应答客户端的请求
    • 3:交互中。Http头信息已经接收,响应数据尚未接收。
    • 4:完成。数据接收完成

这里写图片描述

  • responseText:服务器返回的文本内容
  • responseXML:服务器返回的兼容DOM的XML内容
  • status:服务器返回的状态码
  • statusText:服务器返回状态码的文本信息

上面有两个地方都提及了回调函数,回调函数是什么??

回调函数就是接收服务器返回的内容!

这里写图片描述


编写第一个Ajax程序

检测用户输入的用户名是否为”zhongfucheng”,只要不是zhongfucheng,就可以使用!

html代码

  • 创建的div只要用于显示服务器返回的数据
  • 当用户点击按钮的时候,就触发事件。
  1.  
     
  2.  
    <input type="text" id="username">
  3.  
    <input type="button" οnclick="checkUsername()" value="检测用户名是否合法">
  4.  
    <div id="result">
  5.  
     
  6.  
    </div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

JavaScript代码

  • 创建XMLHttpRequest对象
  • 创建http请求
  • 把文本框的数据发送给http请求的目标
  • 指定回调函数
  • 编写回调函数
  • 发送http请求
  • 回调函数得到http返回的内容,把内容写在div上
  1.  
     
  2.  
     
  3.  
    <script type="text/javascript">
  4.  
     
  5.  
    var httpRequest;
  6.  
    function checkUsername() {
  7.  
     
  8.  
    if(window.XMLHttpRequest) {
  9.  
     
  10.  
    //在IE6以上的版本以及其他内核的浏览器(Mozilla)等
  11.  
    httpRequest = new XMLHttpRequest();
  12.  
    } else if(window.ActiveXObject) {
  13.  
     
  14.  
    //在IE6以下的版本
  15.  
    httpRequest = new ActiveXObject();
  16.  
    }
  17.  
     
  18.  
     
  19.  
    //创建http请求
  20.  
    httpRequest.open( "POST", "Servlet1", true);
  21.  
     
  22.  
    //因为我使用的是post方式,所以需要设置消息头
  23.  
    httpRequest.setRequestHeader( "Content-type", "application/x-www-form-urlencoded");
  24.  
     
  25.  
    //指定回调函数
  26.  
    httpRequest.onreadystatechange = response22;
  27.  
     
  28.  
    //得到文本框的数据
  29.  
    var name = document.getElementById("username").value;
  30.  
     
  31.  
    //发送http请求,把要检测的用户名传递进去
  32.  
    httpRequest.send( "username=" + name);
  33.  
     
  34.  
    }
  35.  
     
  36.  
    function response22() {
  37.  
     
  38.  
    //判断请求状态码是否是4【数据接收完成】
  39.  
    if(httpRequest.readyState==4) {
  40.  
     
  41.  
    //再判断状态码是否为200【200是成功的】
  42.  
    if(httpRequest.status==200) {
  43.  
     
  44.  
    //得到服务端返回的文本数据
  45.  
    var text = httpRequest.responseText;
  46.  
     
  47.  
    //把服务端返回的数据写在div上
  48.  
    var div = document.getElementById("result");
  49.  
    div.innerText = text;
  50.  
    }
  51.  
     
  52.  
    }
  53.  
    }
  54.  
    </script>
  55.  
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

效果

实现了局部更新,不需要刷新整一个页面

这里写图片描述


XMLHttpRequest解决中文乱码

在传统的Web中我们已经解决过中文乱码问题了。

  • 服务器传送给浏览器数据发生乱码:response设置编码的时候和浏览器页面的编码一致便可以解决
  • 浏览器传送给服务器数据发生乱码:如果是post方式,request设置编码便可以解决。如果是get方式,Tomcat下,使用ISO8859-1编码得到原本的二进制数组,再使用UTF-8编码便可以解决

接下来,要介绍的是:我们可以屏蔽任何浏览器和任何服务器的编码格式,浏览器发送给服务器的数据不造成乱码问题!

具体我们是这样做的:

  • 发送数据给服务器的时候,JavaScript使用两次EncodeURI()
  • 服务器得到数据,使用URLEncode.decode(数据,”utf-8”)进行解码

为啥我能说这种方式屏蔽任何浏览器和服务器的编码格式,都不会乱码呢??

这里写图片描述


XMLHttpRequest解决缓存问题

在传统的Web中我们也解决过缓存的问题,通过设置response的头信息,返回给浏览器就可以实现不缓存页面了。

但是呢,现在我们使用XMLHttpRequest,拿到的不是全新的页面,仅仅是服务器端发送过来的数据!!

那我们要怎么解决缓存的问题呢??产生缓存的原因就是:我们请求了同一个地址,做了相同的操作。服务端认为我的操作并没有什么变化,就直接把缓存的信息给我了。这样的话,我就不能更换验证码图片了(等等应用)。

我们可以这样做:

  • 在每次请求url中加入一个时间戳参数【每次url就不一样了】
  • 加入时间戳参数到url时,也分两种情况
    • url本身就带有参数了,也就是说有”?”号了,那么添加时间戳的时候就需要用”&”号
    • url没有参数,直接使用”?”号来添加时间戳
  1.  
     
  2.  
    if(url.indexOf("?") >= 0){
  3.  
    url = url + "&t=" + (new Date()).valueOf();
  4.  
    } else{
  5.  
    url = url + "?t=" + (new Date()).valueOf();
  6.  
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

XMLHttpRequest跨域访问

使用XMLHttpRequest去跨域访问是会出现错误的。

这里写图片描述

我们要怎么解决呢??这时候就要用代理思想了

  • XMLHttpRequest先把请求提交给同域的Servlet处理
  • 同域Servlet再将XMLHttpRequest的请求提交给跨域的服务器
  • 同域Servlet得到跨域服务器的返回值,再返回给XMLHttpRequest

这里写图片描述

这个时候,XMLHttpRequest跨域访问就分两种(GET和POST)情况了,因为这两种提交数据的方式是不一样的!

浏览器代码

  • 我们需要在调用open方法之前判断一下要连接的地址是不是以http开头的,如果是则认为要访问的是跨域的资源
  • 首先将当前url中的”?”变成”&”,这是因为将要连接的地址改为”Proxy?url=” + url以后,如果原来url地址中有参数的话,新的url地址中就会有两个“?”这会导致服务器端解析参数错误,”url=”之后的内容表示本来要访问的跨域资源的地址。

GET方式

GET方式是直接把参数的信息都放在url地址上,所以处理起来会相对简单。

步骤:

  • 使用StringBuilder装载着getParameter(“url”)【获取得到地址,呆会要做拼接,所以用StringBuilder】
  • 得到其他参数的时候,做URLEncode.encode(),因为我们进入Servlet的时候已经被decode了一次【我们要尽可能保留原始请求】(参照解决中文乱码)
  • 遍历所有的请求参数,只要名字不是”url”,就添加到StringBuilder中【第一个参数为”?”,其他的参数为”&”】(http://localhost:8080/url?aa=bb&cc=dd)
  • 创建URL对象,把拼接成的StringBuilder传递进去
  • 使用BufferReader读取远程服务器返回的数据,要指定输入流编码格式,否则会乱码
  1.  
     
  2.  
    BufferedReader reader = new BufferedReader(new InputStreamReader(URL对象.openSteam(),"UTF-8"));
  • 1
  • 2
  • 3
  • 最后,把远程服务器读取到的数据再返回给XMLHttpRequest

POST方式

POST方式把参数的信息都封装到HTTP请求中,在URL进行连接的时候,需要把数据写给远程服务器

步骤:

  • 得到url参数,创建StringBuilder
  • 得到其他参数的时候,做URLEncode.encode(),因为我们进入Servlet的时候已经被decode了一次【我们要尽可能保留原始请求】(参照解决中文乱码)
  • 遍历所有的请求参数,只要名字不是”url”,就添加到StringBuilder中【第一个参数直接给出,其他的参数为”&”】(aa=bb&cc=dd&ee=ff)
  • 创建URL对象,创建URL连接器,允许写数据到远程服务器上
  1.  
    URL url = new URL(url);
  2.  
    URLConnection connection = url.openConnection;
  3.  
    connection.setDoOutPut( true);
  4.  
     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 得到写数据流
  1.  
     
  2.  
    OutputSteamWriter writer = new OutputSteamWriter(conncetion.getOutputSteam)
  3.  
     
  • 1
  • 2
  • 3
  • 把StringBuilder的数据写到远程服务器上,并flush
  • 使用BufferReader读取远程服务器返回的数据
  1.  
     
  2.  
    BufferedReader reader = new BufferedReader(new InputSteamReader(conncetion.inputSteamReader,"UTF-8"));
  • 1
  • 2
  • 3

总结图

猜你喜欢

转载自www.cnblogs.com/gfgfe45/p/12151824.html