Ajax入门

Posted SeptemberNotes

tags:

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

Ajax入门

没有使用Ajax之前在前后端进行数据传输的时候,一般我们就是在前端页面写一个form表单,在后端定义好对象进行数据绑定,只要我们以get/post的方式把表单提交到对应的API接口,我们就能获取到对象的值(不出啥意外的情况下),是的,我们确实可以通过这样的方式在前端提交数据到服务器,也可以从服务器返回数据到前端进行渲染展示。

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

  • 性能会有所降低(一点局部内容修改,刷新整个页面)

  • 用户操作的页面会中断(整个页面都被刷新了,你正在填写的表单数据没了,又要重新再写一遍!)

为什么使用Ajax

Ajax的全称是Asynchronous javascript and XML中文名称定义为异步的JavaScript和XML。

传统的web应用,当我们提交一个表单请求给服务器,服务器接收到请求之后,返回一个新的页面给浏览器,这种做法浪费了很多带宽,由于每次用户的交互都需要向服务器发送请求,应用的访问时间取决于服务器的返回时间。使用Ajax,客户端与服务器可以在不必刷新整个浏览器的情况下,与服务器进行异步请求通信。Ajax就是能做到页面局部刷新。

Ajax实际上是下面这几种技术融合:
  1. Xhtml和CSS的基于标准的表示技术

  2. DOM进行动态显示和交互

  3. XML和XSLT进行数据交换和处理

  4. XMLHttpRequest进行异步数据检索

  5. JavaScript将以上技术融合在一起

XMLHttpRequest

XMLHttpRequest对象是Ajax最重要的一个对象,使用Ajax更多的是编写客户端代码,而不是服务端。
传统的web前端与后端的交互中,浏览器直接访问Tomcat的Servlet来获取数据。Servlet通过转发把数据发送给浏览器。当我们使用AJAX之后,浏览器是先把请求发送到XMLHttpRequest异步对象之中,异步对象对请求进行封装,然后再与发送给服务器。服务器并不是以转发的方式响应,而是以流的方式把数据返回给浏览器。

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

创建XMLHttpRequest对象

要创建XMLHttpRequest对象是要分两种情况考虑:1.在IE6以下的版本、2.在IE6以上的版本以及其他内核的浏览器(Mozilla)等。

    <script type="text/javascript">
        var httpRequest;
        if(window.XMLHttpRequest) {
            //在IE6以上的版本以及其他内核的浏览器(Mozilla)等
            httpRequest = new XMLHttpRequest();
        }else if(window.ActiveXObject) {

            //在IE6以下的版本
            httpRequest = new ActiveXObject();
        }
    
</script>
了解XMLHttpRequest对象的属性和方法
  • open(String method,String url,boolean asynch,String username,String password)

  • setRequestHeader(String header,String value)

设置消息头(使用post方式才会使用到,get方法并不需要调用该方法)
格式:xmlhttp.setRequestHeader

("Content-type","application/x-www-form-urlencoded");

  • send(content)

发送请求给服务器,其内容可以是DOM对象,输入流或是字符串。
调用open 方法后,可以调用send()方法来发送请求。
当open 中asynch=true时,send()方法调用后立即返回,否则会中断直到请求返回。
方法参数:

  • 如果是get方式,并不需要填写参数,或填写null

  • 如果是post方式,把要提交的参数写上去


上面的方法比较常用,下面的方法不是很常用

  • getAllResponseHeaders()

getAllResponseHeaders()方法返回所有的HttpResponse头部信息。

  • getResponseHeader(String header)

返回包含HTTP的所有响应头信息,其中响应头包括Content-Length,Date,URI等内容。

  • abort()

可以暂停一个HttpRequest请求或者HttpResponse的接收,并且将XMLHttp
Request的状态设置为初始化。

属性
  • onreadystatechange

请求状态改变的时间触发器【readyState状态发生变化时会调用此方法】,一般用于指定回调函数。

  • readyState

请求状态readyState一改变,回调函数被调用,它有5个状态,回调函数就是接收服务器返回的内容。
0:未初始化。
1: open() 方法已调用,但是send()方法未调用。请求还没有被发送。
2: 服务器已经应答客户端的请求,Send()方法已调用,HTTP 请求已发送到 Web 服 务器。未接收到响应。
3: 交互中。所有响应头部都已经接收到。响应体开始接收但未完成。
4: 完成。数据接收完成。

  • responseText

服务器返回的文本内容

  • responseXMl

服务器返回的兼容DOM的XML内容

  • status

服务器返回的状态码

  • statusText

服务器返回的状态码文本信息

编写第一个Ajax程序

前端页面:这里使用的是IDEA作为开发工具,使用的是SpringBoot+thymeleaf+bootstrap,以及引入了bootstrap.css、jquery.min.js、bootstrap.js。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link th:href="@{/bootstrap3/css/bootstrap.css}" rel="stylesheet" type="text/css">
</head>
<body>
     <button class="btn btn-success" id="search">查询</button>
     <span id="username"></span>
</body>
<script type="text/javascript" src="webjars/jquery/2.2.4/jquery.min.js"></script>
<script th:src="@{/bootstrap3/js/bootstrap.js}"></script>
<script>
    document.getElementById("search").onclick = function () {
        var request=new XMLHttpRequest();//创建XMLHttpRequest对象
        request.open("GET","/users");
        // request.setRequestHeader("Content-Type", "application/x-wwww-form-urlencoded");
        request.send();
        request.onreadystatechange = function () {
            if (request.readyState==4){ //是否数据接收完成
                if (request.status==200){ //返回的状态码
                    document.getElementById("username").innerHTML = request.responseText;
                   //将返回的数据赋值到<span>中
                } else {
                    alert("发生错误:"+request.status);
                }
            }
        }
    }
</script>
</html>

服务器代码:

@Controller
public class UserController {
    List<User> list = new ArrayList<>();
    @GetMapping(value = "/users")
    @ResponseBody
    public List<User> getUserAll(){
        User user = new User();
        user.setUserId(1);
        user.setUserName("September");
        user.setEmail("jiuyue@163.com");
        list.add(user);
        return list;
    }
}

效果:实现了局部更新,不需要刷新整一个页面[页面没有跳转]

使用get请求图

XMLHttpRequest解决缓存问题

在传统的Web中我们也解决过缓存的问题,通过设置response的头信息,返回给浏览器就可以实现不缓存页面了。但是呢,现在我们使用XMLHttpRequest,拿到的不是全新的页面,仅仅是服务器端发送过来的数据!

我们可以这样做:

在每次请求url中加入一个时间戳参数【每次url就不一样了】,加入时间戳参数到url时,也分两种情况。

url本身就带有参数了,也就是说有"?"号了,那么添加时间戳的时候就需要用"&"号。
url没有参数,直接使用"?"号来添加时间戳。

    if(url.indexOf("?") >= 0){
    url = url + "&t=" + (new Date()).valueOf();
    } else{
    url = url + "?t=" + (new Date()).valueOf();
    }
使用POST请求
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link th:href="@{/bootstrap3/css/bootstrap.css}" rel="stylesheet" type="text/css">
</head>
<body>
<button class="btn btn-success" id="search">查询</button>
<button class="btn btn-success" onclick="addUser()">addUser</button>
<button class="btn btn-success" id="save">添加</button>
        <span id="username"></span>
        <div class="form-group">
            <label class="label">请输入姓名:</label>
            <input id="name" name="name" type="text" placeholder="请输入姓名">
        </div>
        <div class="form-group">
            <label class="label">请输入住址:</label>
            <input id="address" name="address" type="text" placeholder="请输入住址">
        </div>
</body>
<script type="text/javascript" src="webjars/jquery/2.2.4/jquery.min.js"></script>
<!--<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>-->
<script th:src="@{/bootstrap3/js/bootstrap.js}"></script>
<script>
    document.getElementById("save").onclick = function () {
        var request = new XMLHttpRequest();
        request.open("POST","/save");
        var name= document.getElementsByName("name")[0].value;//使用getElementsByName
        var address= document.getElementById("address").value;//使用getElementById(value不带values())
        request.setRequestHeader("Content-type""application/x-www-form-urlencoded");
        // request.send("name=jiuyue&address=wuhan");
        var data = "name="+name+"&address="+address;
        request.send(data);
        request.onreadystatechange = function () {
            if (request.readyState==4){ //是否数据接收完成
                if (request.status==200){  //返回的状态码
                    document.getElementById("username").innerHTML = request.responseText;
                } else {
                    alert("发生错误:"+request.status);
                }
            }
        }
    }
</script>
</html>

后端代码:

    @PostMapping("/save")
    @ResponseBody
    public User save(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        String name = request.getParameter("name");
        String address = request.getParameter("address");
        System.out.println("name:"+name);
        System.out.println("address:"+address);
        User user = new User();
        user.setUserId(2);
        user.setUserName(name);
        user.setEmail(address);
        return user;
    }


效果如下:

Ajax入门

使用post请求图

这里需要注意的是:我前面使用字符串拼接方式,也就是下面的方式给data对象赋值。但是获得到的值name、address都是undefine.

var data = "name="+document.getElementsByName("name").value
        +"&address="+document.getElementsByName("address").value;
request.send(data);

测试了很久,快要放弃的时候换了下面的拼接方式就可以了。

var name= document.getElementsByName("name")[0].value;//使用getElementsByName
var address= document.getElementById("address").value;//使用getElementById(value不带values())
request.setRequestHeader("Content-type""application/x-www-form-urlencoded");
var data = "name="+name+"&address="+address;
request.send(data);
另一种POST请求的方式

前端JavaScript如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link th:href="@{/bootstrap3/css/bootstrap.css}" rel="stylesheet" type="text/css">
</head>
<body>
<button class="btn btn-success" id="search">查询</button>
<button class="btn btn-success" onclick="addUser()">addUser</button>
<button class="btn btn-success" id="save">添加</button>
        <span id="username"></span>
        <div class="form-group">
            <label class="label">请输入姓名:</label>
            <input id="name" name="name" type="text" placeholder="请输入姓名">
        </div>
        <div class="form-group">
            <label class="label">请输入姓名:</label>
            <input id="address" name="address" type="text" placeholder="请输入住址">
        </div>
</body>
<script type="text/javascript" src="webjars/jquery/2.2.4/jquery.min.js"></script>
<!--<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>-->
<script th:src="@{/bootstrap3/js/bootstrap.js}"></script>
<script>
    function addUser() {
        var name= document.getElementsByName("name")[0].value;//使用getElementsByName
        var address= document.getElementById("address").value;//使用getElementById(value不带values())
        var data = {name:name,address:address};
        $.ajax({
            type:"POST",
            dataType:"json",
            url:"/save",
            // data:{"name":"jiuyue","address":"wuhan"},
            data:data,
            success:function (data{
                var result = JSON.stringify(data);//将返回的json数据转换成String
                document.getElementById("username").innerHTML = result;
            }
        });
    }
</script>
</html>

后端与上面的一样,没有任何修改。

使用post请求图

“扫码关注“


以上是关于Ajax入门的主要内容,如果未能解决你的问题,请参考以下文章

推荐net开发cad入门阅读代码片段

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

前端面试题之手写promise

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

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

javascript AJAX片段