ajax基础知识

Posted 一路晨光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ajax基础知识相关的知识,希望对你有一定的参考价值。

ajax技术(JavaScriptXML的综合)


全称:Asynchronous(异步) javascript And XML (异步的JavaScript和XML)。

1. ajax是一种用来改善用户体验的技术,其实质是利用浏览器内置的一个特殊的对象(XMLHttpRequest一般称之为ajax对象),异步地(当ajax对象发请求时,浏览器不会销毁当前页面,用户任然可以对当前页面做其的操作)向服务器发送请求,服务器送回部分数据(不是完整的页面),利用这些数据更新当前页面。整个过程,页面无刷新,不打断用户的操作。

2. ajax对象是BOM模型里的,几乎所有的浏览器都有这个对象。

3. Ajax技术是若干技术的综合应用,主要涵盖JavaScript,XMLHttpRequest(发请求接收响应信息),XML,html,CSS.(这些技术融合在一起就是Ajax)。

 

ajax技术的优点


1. 页面无刷新,不打断用户的操作。

2. 浏览器与服务器之间可以按照需要获取数据,不需要再传送一个完整的页面。也就是说,浏览器与服务器之间数据传输量大大减少。(性能有所提高)

3. 是一种标准化的技术,不需要浏览器额外去下载一些插件。

作用:用于客户端和服务器端交互的一项技术.主要用于页面的局部刷新,不需要刷新整个页面,提升用户的体验度

原有交互主要基于提交表单,采用点超连接方式,这种方式主要有以下一些弊端:

a. 请求发出后,如果响应速度慢,客户需要等待,而且是茫然的等待

b. 请求响应回来需要刷新整个页面,如果页面中有需要频繁更新的数据,会造成整个页面的频繁刷新.(而实际:只有某个区域需要刷新,不需要整个页面刷新.)

采用Ajax技术之后,可以解决以上问题.提升用户的体验度

 

Ajax技术原理


Ajax技术使用时,需要编写客户端脚本和服务器端处理程序。原理如下:

1. 首先客户端利用JavaScript创建一个XMLHttpRequest对象

2. 利用XMLHttpRequest对象(ajax引擎),创建和发送一个请求

3. 请求到达服务器,调用Servlet组件处理,处理完毕后,返回响应数据,数据可以采用字符串或XML格式返回。

4. XMLHttpRequest接收到服务器返回的数据,调用客户端的回调函数,将数据更新到页面

 

如何获得XMLHttpRequest对象?


因为XMLHttpRequest没有标准化,要区分浏览器来获得这个对象:

function getXhr(){
    var xhr=null;
    if(window.XMLHttpRequest){
        //非IE浏览器
        xhr = new XMLHttpRequest();
    }else{
        //IE浏览器
        xhr = new ActiveXObject(‘Microsoft.XMLHttp’);
    }
    return xhr;
}    

 

XMLHttpRequest对象的使用


该对象是由浏览器提供的,在IE中该对象以ActiveXobject组件形式存在,在其他浏览器中以XMLHttpRequest形式存在。

XMLHttpRequest对象主要的函数和属性

open(param1,param2,param3)函数

创建一个请求,与服务器之间建立连接。

param1:用于指定请求类型,可以是"get","post"。get请求必须将请求参数添加到请求资源路径的后面。

param2:用于指定请求URL地址

param3:用于指定请求发出方式:true异步(默认的),false表示同步。

异步请求:发请求时,浏览器不会销毁当前页面,用户可以对当前页面做其他操作

同步请求:发请求时,浏览器不会销毁当前页面,浏览器会锁定当前页面,用户不能对当前页面做其他操作,只有请求处理完成返回时,用户才可以继续做其他操作。

同步:(请求1-响应1)(请求2-响应2)必须要在第一个请求得到响应后在能发第二次请求

同步模式:请求1-->响应1回调执行-->请求2

异步:(请求1,请求2,) (响应1,响应2,) 不需要第一个请求得到响应后再发第二次请求

异步模式:请求1-->请求2-->响应1回调执行

 

send(param1)函数

发送一个请求,把open的请求发出去。

param1:用于指定请求发送时提交的数据。如果是get请求,param1指定为null。如果是post请求,需要指定为"key=value&key=value"

 

onreadystatechange事件

用于指定注册的回调函数.指定函数名不需要()。该事件在readyState属性值发生改变时触发该事件。当ajax对象的readyState属性值发生了改变(比如从0变成了1),则会产生readystatechange事件。

 

readyState属性

readyState有5个值,分别是0,1,2,3,4,表示ajax对象与服务器进行通信时的状态。比如,值为4时表示ajax对象已经成功德获得了服务器返回的所有的数据。只有当readyState的值等于4时,才能使用responseText等属性获得服务器返回的数据。           

0          请求未初始化(对象已建立,但是尚未初始化)        open函数未调用

1          请求已初始化                 open调用,send未调用

2          请求已发送                     send方法已调用

3          请求正在处理中

4          请求处理完毕

状态会自动改变。每次状态改变时都会触发onreadystatechange事件.即会调用一次回调函数

 

status属性

用于获取请求处理的状态码。例如:404 500 200等  404:找不到处理资源  500:找到资源,执行出错  200:执行成功

 

responseText属性

用于获取服务器处理返回的字符串信息。需要在readyState==4&&status==200执行,才可以获取正常数据

 

responseXML属性

用于获取服务器处理返回的XML结果对象。很少使用,因为解析XML文件比较慢,XML文件也比较大。

 

Ajax程序的编写步骤


step1、获得XMLHttpRequest对象,var xhr=getXhr();

step2、发送请求(get请求,post请求)

step3、编写服务器端的处理程序,一般服务器只需返回部分的数据。

step4、编写事件处理函数

示例:焦点移开,检查用户名非空和唯一性

my.js

function getXhr(){
    var xhr=null;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject(‘Microsoft.XMLHttp‘);
    }
    return xhr;
}

regist.jsp

<html>
    <head>
    <script type="text/javascript" src="<%=request.getContextPath() %>/js/my.js"></script>
    <script type="text/javascript" src="<%=request.getContextPath() %>/js/prototype-1.6.0.3.js"></script>
    <script type="text/javascript">
        function check_username(){
            var username=$F(username);
            if(username==""){
                $("span_username").innerHTML="用户名不能为空。。";
            }else{
                var xhr=getXhr();
                xhr.open("get","checkUsername.do?username="+username,true);
                xhr.onreadystatechange = function(){
                    if(xhr.readyState==4){
                        if(xhr.status==200){
                            var txt=xhr.responseText;
                            $("span_username").innerHTML=txt;
                        }else{
                            $("span_username").innerHTML="系统异常,稍后重试...";
                        }

                    }
                };
                $("span_username").innerHTML="正在检查。。。。";
                xhr.send(null);    
            }
        }
    </script>
</head>
<body>
    <fieldset>
        <legend>注册</legend>
        <form action="regist.do" method="post">
             用户名:<input type="text" name="username" onblur="check_username();" id="username"/><span style="color:red;" id="span_username">${regist_error }</span><br>
            密码:<input type="password" name="pwd" onblur="check_pwd();"/><br>
            <input type="submit" value="注册" />
        </form>
    </fieldset>
</body>
</html>

ActionServlet

public class ActionServlet extends HttpServlet{
  protected void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
    request.setCharacterEncoding("utf-8");
    response.setContentType("text/html;charset=utf-8");
    PrintWriter out=response.getWriter();
    String uri=request.getRequestURI();
    String action=uri.substring(uri.lastIndexOf(‘/‘),uri.lastIndexOf(‘.‘));
    if(action.equals("/checkUsername")){
      Thread.sleep(5000);
      String username=request.getParameter("username");
      if("张三".equals(username)){
        out.println(
"用户名已经存在");       }else{         out.println("可以使用"); }     }else if(action.equals("/regist")){       //任然要检查用户是否存在
      
String username=request.getParameter("username");       if("zs".equals(username)){         request.setAttribute("regist_error", "用户名被占用");         request.getRequestDispatcher("/regist.jsp").forward(request,response);       }else{         System.out.println("注册");       }
   }   } }

 

prototype.js的简单使用


$(id);相当于document.getElementById(id);

$F(id);相当于 $(id).value

$(id1,id2..)依据id1,id2..查找对应的节点,然后将这些节点放到一个数组里面返回。

strip()除掉字符串两端的空格

evalJSON()将符合json语法格式的字符串转换成一个javascript对象。

 

发送post请求


xhr.open("post",url,true);

xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//设置一个消息头。发送post请求,要求浏览器发送一个Content-Type消息头。默认情况下,ajax对象(xhr)不会添加content-type消息头,所以调用setRequestHeader方法来添加这个消息头。

xhr.send("username="+name);

提示:有中文信息提交建议采用Post方式

 

ajax应用当中的编码问题


发送get请求

产生乱码的原因

IE内置的ajax对象会使用“gbk”对中文进行编码,其他浏览器内置的ajax对象会使用“utf-8”对中文进行编码;服务器默认情况下,对于get请求发送过来的数据,会使“ISO-8859-1”进行解码。

解决方式

step1、让服务器使用指定的编码格式进行解码。比如:可以修改tomcat的配置文件conf/server.xml,添加URIEncoding="utf-8"

 <Connector connectionTimeout="20000" port="8088" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="utf-8"/>

step2、使用全局函数encodeURI函数对请求地址进行编码

xhr.open("get",encodeURI("check_username.do?username=‘张三‘"),true);

 

发送post请求

xhr.open(‘post’,’check_username.do’,’true’);

乱码产生的原因

采用post请求方式,浏览器内置的ajax对象,对中文参数都使用”utf-8”进行编码。服务器端:如果是火狐发送请求,服务器端采用utf-8解码。其他浏览器是is0-8859-1解码。

因为发送的content-type消息头

火狐:Content-Type        application/x-www-form-urlencoded; charset=UTF-8

其他:Content-Type: application/x-www-form-urlencoded;

火狐带有utf-8。这样服务器端采用utf-8解码,而不是iso-8859-1去解码

解决方式

服务器端:request.setCharacterEncoding="utf-8";

 

缓存问题


1. 什么是缓存问题?

在使用IE浏览器时,如果使用get方式发送请求,浏览器会将数据缓存起来。这样,当再次发送请求时,如果请求地址不变,IE不会真正地向服务器发请求,而是将之前缓存的数据显示给用户。只有IE浏览器才会有缓存问题

2. 解决方式:

a. 使用post方式(post请求不会缓存)

b. 为了避免缓存问题,可以在URL后面追加一组参数,该参数值可以使用随机值或者时间戳。随机值:Math.random()  时间戳:new Date().getTime()

 

同步问题


浏览器是单线程的,设置成同步之后,发送请求就一直等待服务器的处理结果、浏览器没有其他的线程来处理其他事。 一般数据验证的时候用同步请求。要等服务器返回数据后,才可以做其他事。

 




以上是关于ajax基础知识的主要内容,如果未能解决你的问题,请参考以下文章

AJAX相关JS代码片段和部分浏览器模型

Javascript代码片段在drupal中不起作用

前端面试题之手写promise

Ajax 片段元标记 - Googlebot 未读取页面内容

执行AJAX返回HTML片段中的JavaScript脚本

javascript AJAX片段