Ajax

Ajax (Asynchronous Javascript And XML)(异步 JavaScript 和 XML),无需重新加载整个网页的情况下,能够更新部分网页的技术。(异步刷新)

场景:看电影看了一半,点赞

  • 全局刷新:访问后台,全局刷新,视频重新加载,崩溃
  • 异步刷新:访问后台,只刷新点赞数,视频无需重新加载

一、基于XML的Ajax

JavaScript实现Ajax(基于XML),需要操作一个对象XMLHttpRequest对象

1.1 XMLHttpRequest对象的常用方法

  • open(method,url,true):与服务器建立连接

    • method:请求方式
    • url:服务器地址
    • true:固定写法,是否为异步请求
  • send():发送参数

    • get方式:send(null),直接在url发送参数(?xxx=xxx&yyy=yyy)
    • post方式 :send(参数值)
      • json数据需要 JSON.stringify() 封装
  • setRequestHeader(header,value):设置请求头

    • get方式:不需要此方法(get方式没有请求头)

    • post方式:需要设置

      • 请求元素中包含文件上传:

        setRequestHeader(“Content-Type”,“multipart/form-data”)

        • 注意:如果使用FormData对象,不用设置,FormData默认使用multipart/form-data
      • 不包含文件上传

        setRequestHeader(“Content-Type”,“application/x-www-form-urlencoded”)

      • json数据

        setRequestHeader(“Content_Type”,“application/json”)

  • onreadyStatechange:回调函数

  • readyState:请求状态 只有状态为4代表请求完毕

  • stauts:响应状态 只有200代表响应正常

  • responseText:响应格式String

  • responseXML:响应格式XML

1.2 POST请求

前台jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    
    <script type="text/javascript" >
        //点击事件
        function testClick(){
            //获取name的值
            var name =document.getElementById("n").value ;
            //创建XMLHttpRequest对象连接后台
            xr = new XMLHttpRequest();
            //连接后台
            xr.open("post","${pageContext.request.contextPath}/test/json",true);
            //设置回调函数
            xr.onreadystatechange=callback ;
            //设置请求头
            xr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            //发送参数
            xr.send("name="+name);
        }

        //回调函数
        function callback(){
            //请求正常和响应正常
            if (xr.readyState==4&&xr.status==200){
                var result = xr.responseText;
                alert(result)
                if (result=="success"){
                    alert("服务器接收到参数")
                }else{
                    alert("服务器未接收到参数")
                }
            }
        }
    </script>
</head>
    <body>
            姓名<input id="n"  name="name" >
            <input type="button" value="提交" οnclick="testClick()">


    </body>
</html>

服务器

方式一:原生servletAPI响应

	@RequestMapping(value = "json" ,method = RequestMethod.POST)
    public void  json(String name, HttpServletResponse response) throws IOException {
        if (name!=null&name.length()!=0){
            System.out.println(name);
            response.getWriter().write("success");
        }else{
            response.getWriter().write("error");
        }
    }


方式二:SprigMVC的ResponseBody响应

	@ResponseBody
    @RequestMapping(value = "json" ,method = RequestMethod.POST)
    public String  json(String name) {
        if (name!=null&name.length()!=0){
            System.out.println(name);
            return "success" ;
        }else{
            return "error" ;
        }
    }

执行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xfr6RnsU-1585559126700)(C:\Users\333\AppData\Roaming\Typora\typora-user-images\1585534464735.png)]

1.3 GET请求:(没有请求头,参数写在url上)

	<script type="text/javascript" >
        //点击事件
        function testClick(){
            //获取name的值
            var name =document.getElementById("n").value ;
            //创建XMLHttpRequest对象连接后台
            xr = new XMLHttpRequest();
            //连接后台
            xr.open("get","${pageContext.request.contextPath}/test/json?name="+name,true);
            //设置回调函数
            xr.onreadystatechange=callback ;
            //发送参数
            xr.send(null);
        }

        //回调函数
        function callback(){
            //请求正常和响应正常
            if (xr.readyState==4&&xr.status==200){
                var result = xr.responseText;
                alert(result)
                if (result=="success"){
                    alert("服务器接收到参数")
                }else{
                    alert("服务器未接收到参数")
                }
            }
        }
    </script>

1.4 Json格式数据传送

	<script type="text/javascript" >
        function testClick(){
            var name =document.getElementById("n").value ;
            xr = new XMLHttpRequest();
            xr.open("post","${pageContext.request.contextPath}/test/json",true);
            xr.onreadystatechange=callback ;
            
            //设置请求头
            xr.setRequestHeader("Content-Type","application/json");
            //发送参数
            xr.send(JSON.stringify({"accountName":name,"accountId":"001"}));
        }

    </script>

1.5 基于XML的Ajax文件上传

使用formData对象封装form表单中的文件与普通参数

  • 使用append(”name“,value)方法添加参数,name为参数名,value为值
  • 使用getElementById(“id”).files 获取文件数组
  • 使用getElementById(“id”).value 获取参数值

注意:

  • formData传递参数默认的enctype为multipart/form-data,所以不需要再设置请求头(会报错)
  • 若使用SpringMVC中的multipartResolver解析参数,则request中已经没有文件,所以再使用ServletFileupload解析request为空
  • SpringMVC解析与ServletFileupload解析不能混用

1.5.1 ServletFileupload方式上传文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" >
        //点击事件
        function testClick(){
            //获取表单name的值
            var name =document.getElementById("n").value ;
            //获取表单file的值
            var file =document.getElementById("file").files ;
            var data = new FormData();
            data.append("name",name);
            data.append("file",file[0]);
            //创建XMLHttpRequest对象连接后台
            xr = new XMLHttpRequest();
            //连接后台
            xr.open("post","${pageContext.request.contextPath}/test/json",true);
            //设置回调函数
            xr.onreadystatechange=callback ;
            //不能再设置请求头为multipart/form-data
            // xr.setRequestHeader("Content-Type","multipart/form-data");
            //发送参数
            xr.send(data);
        }

        //回调函数
        function callback(){
            //请求正常和响应正常
            if (xr.readyState==4&&xr.status==200){
                var result = xr.responseText;
                alert(result);
                if (result=="success"){
                    alert("上传成功")
                }else{
                    alert("上传失败")
                }
            }
        }
    </script>
</head>
<body>
        姓名<input id="n"  name="name" ><br>
        文件<input id="file"  name="file" type="file"><br>
        <input type="button" value="提交" οnclick="testClick()">


</body>
</html>
	@ResponseBody
    @RequestMapping(value = "/json" ,method = RequestMethod.POST)
    public String  json(HttpServletRequest request) throws Exception {
        //获取项目的绝对路径+/upLoad/
        String path = request.getSession().getServletContext().getRealPath("/upLoad/");
        //控制打印项目真实地址
        System.out.println(path);
        File file = new File(path);
        //判断文件夹是否存在
        if (!file.exists()) {
            //创建文件夹
            file.mkdirs();
        }

        //判断前台数据是否有multipart/form-data
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        //不存在Multipart
        if (!isMultipart){
            return "error" ;
        }
        //创建FileItem工厂
        FileItemFactory fileItemFactory = new DiskFileItemFactory() ;
        //创建文件上传Servlet(需要一个FileItem工厂)
        ServletFileUpload fileUpload = new ServletFileUpload(fileItemFactory);
        //解析request
        List<FileItem> fileItems = fileUpload.parseRequest(request);
        //生成迭代器
        Iterator<FileItem> iterator = fileItems.iterator();
        //遍历迭代器
        while(iterator.hasNext()){
            FileItem fileItem = iterator.next();
            //判断是否为文件类型
            if (fileItem.isFormField()){
                //普通类型
                //获取参数名称
                String name = fileItem.getFieldName();
                //获取参数值(指定字符集)
                String value = fileItem.getString("UTF-8");
                //控制台打印参数
                System.out.println(name+"="+value);
            }else{
                //文件类型
                String fileName = fileItem.getName();
                //使用UUID定义唯一文件名
                String uuid = UUID.randomUUID().toString().replace("-", "");
                //上传文件
                fileItem.write(new File(file,uuid+"_"+fileName));
                //删除内存中的临时文件
                fileItem.delete();
                //控制台打印测试
                System.out.println(fileItem.getFieldName()+"上传成功");
                return "success" ;
            }
        }
        return "error" ;
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z4bfJSni-1585559126702)(C:\Users\333\AppData\Roaming\Typora\typora-user-images\1585546763341.png)]

1.5.2 SpringMVC方式上传文件

注意:MultipartFile与前台的文件名要一致

配置CommonsMultipartResolver的bean

	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="102400">
   		</property>
    </bean>

测试

	//注意MultipartFile与前台的文件名要一致
	@ResponseBody
    @RequestMapping(value = "/json" ,method = RequestMethod.POST)
    public String  json(@RequestParam("name")String name , MultipartFile multipartFile ,HttpServletRequest request) throws Exception {
        //获取项目的绝对路径+/upLoad/
        String path = request.getSession().getServletContext().getRealPath("/upLoad/");
        //控制打印项目真实地址
        System.out.println(path);
        File file = new File(path);
        //判断文件夹是否存在
        if (!file.exists()) {
            //创建文件夹
            file.mkdirs();
        }
        //控制台打印测试name参数
        if (name!=null)
            System.out.println(name);
        if (multipartFile!=null){
            //获取文件名
            String fileName = multipartFile.getOriginalFilename();
            //使用UUID定义唯一文件名
            String uuid = UUID.randomUUID().toString().replace("-", "");
            //上传文件
            multipartFile.transferTo(new File(file,uuid+"_"+fileName));
            //控制台打印测试
            System.out.println("上传成功");
            return "success" ;
        }
        return "error" ;

    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JBKPsmpE-1585559126702)(C:\Users\333\AppData\Roaming\Typora\typora-user-images\1585549192213.png)]

二、基于JQuery的Ajax

参考网站:常用方法参数

方法常用参数:

  • url: 发送请求的地址

  • type: 请求方式(post或get)默认为get

  • data :String或Object类型(post请求),get请求在url中指定

  • String类型:key1=value1&key2=value2…

  • Object类型:json数据{key1 : value , key2 : value2 , … }为单个对象,集合

    形式为:[ {key1 : value , key2 : value2 , … } , {key1 : value , key2 : value2 , … } … ]

  • dataType : 服务器返回的数据类型

  • json:json数据

  • text:纯文本格式

  • ……

  • success: 请求成功时回调函数,有两个参数 ( function(data , status ){}

    • data:服务返回数据
    • status:状态码
  • error : 请求失败时调用的函数

  • contentType:内容(参数)类型,默认为“application/x-www-form-urlencoded

2.1 POST请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="static/jquery-3.4.1.js"></script>
    <script type="text/javascript" >
        $(function(){
            //点击事件
            $("#mybutton").click(function(){
               
                //获取name参数的值
                var $name = $("#n").val();
                
                //ajax异步请求
                $.ajax({
                    //请求方式
                    type: "post",
                    //请求路径
                    url: "test/json" ,
                    //请求参数
                    data: "name="+$name+"&age=12" ,
                    //成功回调函数
                    success:function(result){
                        if (result =="success"){
                            alert("成功");
                        }else if (result=="error"){
                            alert("失败");
                        }else{
                            alert("错误");
                        }
                    }
                });
            });
        });
    </script>
    
</head>
<body>
        姓名<input id="n"  name="name" ><br>
        <input id="mybutton"  type="button" value="提交" >

</body>
</html>

@RequestMapping("/json")
    @ResponseBody
    public String json(String name,Integer age){
        System.out.println(name);
        System.out.println(age);
        return name==null||age==0 ? "error" : "success" ;
    }

2.2 GET方式请求

请求参数写在url上

<script type="text/javascript" src="static/jquery-3.4.1.js"></script>
    <script type="text/javascript" >
        $(function(){
            $("#mybutton").click(function(){
                var $name = $("#n").val();
                $.ajax({
                    type: "get",
                    //请求参数写在url上
                    url: "test/json?name="+$name+"&age=23" ,
                    success:function(result){
                        if (result =="success"){
                            alert("成功");
                        }else if (result=="error"){
                            alert("失败");
                        }else{
                            alert("错误");
                        }
                    }
                });
            });
        });
    </script>

2.3 Json数据请求

Json格式

  • 键名称:用双引号 括起
  • 字符串:用使用双引号 括起
  • 数字,布尔类型不需要 使用双引号括起
	<script type="text/javascript" src="static/jquery-3.4.1.js"></script>
    <script type="text/javascript" >
        $(function(){
            $("#mybutton").click(function(){
                var $name = $("#n").val();
                $.post({
                    url:"test/json",
                    data:JSON.stringify({"accountId":23, "accountName":$name}),
                    contentType:"application/json;charset=utf-8",
                    success:function(result) {
                        if (result == "success") {
                            alert("成功");
                        } else if (result == "error") {
                            alert("失败");
                        } else {
                            alert("错误");
                        }
                    }
                });
            });
        });
    </script>
	@RequestMapping("/json")
    @ResponseBody
    public String json(@RequestBody Account account){
        System.out.println(account);
        return account.getAccountName()==null||account.getAccountId()==0 ? "error" : "success" ;
    }

2.4 Json数据响应

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="static/jquery-3.4.1.js"></script>

</head>
<body>

    <input type="button" value="获取" id="getContent" ><br>
    <table width="80%" align="center">
        <tr>
            <td>id</td>
            <td>姓名</td>
        </tr>
        <tbody id="body"></tbody>
    </table>


    <script type="text/javascript" >
        $(function(){
            $("#getContent").click(function(){
                alert("test");
                var html = "" ;
                //ajax请求数据
                $.post("${pageContext.request.contextPath}/test/json",function(result){
                    //取出数据,拼接
                    for (var i = 0; i < result.length; i++) {
                        html+="<tr>"+
                                "<td>"+result[i].accountId+"</td>"+
                                "<td>"+result[i].accountName+"</td>"+
                              "</tr>";
                    }
                    //给表赋值
                    $("#body").html(html);
                });
            });
        });
    </script>

</body>
</html>
	@RequestMapping("/json")
    @ResponseBody
    public List json(){
        List<Account> list = new ArrayList<>();
        Account account1 = new Account() ;
        Account account2 = new Account() ;
        account1.setAccountId(1);
        account1.setAccountName("张三");
        account2.setAccountId(2);
        account2.setAccountName("李四");
        list.add(account1);
        list.add(account2);
        return list ;
    }

执行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8iKLHxpq-1585559126703)(C:\Users\333\AppData\Roaming\Typora\typora-user-images\1585556519179.png)]

2.5 JQuery方式上传文件

Ajax方式中,需要设置:

  • processData : false 使数据不做处理
  • contentType : false 不要设置Content-Type请求头

2.5.1 ServletFileupload方式上传

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="static/jquery-3.4.1.js"></script>

</head>
<body>

    <input type="text" name="name" id="n">
    <input type="file"  id="file">
    <input type="button" value="获取" id="mybutton" >


    <script type="text/javascript" >
        $(function(){
            //点击事件
           $("#mybutton").click(function(){
               //获取name参数的值
               var $name = $("#n").val();
               //获取文件数组
               var file = document.getElementById("file").files ;
               var formData = new FormData();
               //name参数添加到formData中
               formData.append("name",$name) ;
               //获取文件数组中的一个元素,并添加到formData中
               formData.append("multipartFile",file[0]) ;
               //Ajax异步访问服务器
               $.post({
                   url:"test/json" ,
                   data: formData ,
                   contentType:false , //contentType不做处理,使用formData默认的multipart/form-data
                   processData: false , //使数据不做处理
                   //回调函数
                   success: function(result){
                       if (result=="success") {
                           alert("上传成功");
                       }else {
                           alert("上传失败");   
                       }
                       
                   }
               });

           });
        });
    </script>

</body>
</html>
	@ResponseBody
    @RequestMapping(value = "/json" ,method = RequestMethod.POST)
    public String  json(HttpServletRequest request) throws Exception {
        //获取项目的绝对路径+/upLoad/
        String path = request.getSession().getServletContext().getRealPath("/upLoad/");
        //控制打印项目真实地址
        System.out.println(path);
        File file = new File(path);
        //判断文件夹是否存在
        if (!file.exists()) {
            //创建文件夹
            file.mkdirs();
        }

        //判断内容是否Multipart
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (!isMultipart)
            return "error" ;
        //创建FileItem工厂
        FileItemFactory fileItemFactory = new DiskFileItemFactory();
        //创建文件上传servlet
        ServletFileUpload fileUpload = new ServletFileUpload(fileItemFactory);
        //解析request
        List<FileItem> fileItems = fileUpload.parseRequest(request);
        //判断fileItems是否为空
        if (fileItems==null)
            return "error" ;
        //生成迭代器
        Iterator<FileItem> iterator = fileItems.iterator();
        //取出每一个表单项
        while (iterator.hasNext()){
            FileItem item = iterator.next();
            //判断是普通参数还是文件
            if (item.isFormField()){//普通参数
                //获取参数名
                String fieldName = item.getFieldName();
                //获取参数值,指定字符集
                String value = item.getString("utf-8");
                //打印结果
                System.out.println(fieldName+"="+value);

            }else {//文件
                //获取文件名
                String name = item.getName();
                //使用uuid生成唯一字符串
                String uuid = UUID.randomUUID().toString().replace("-", "");
                //写出磁盘
                item.write(new File(file,uuid+name));
                //删除临时文件
                item.delete();
                //打印测试
                System.out.println("上传文件成功");
                return "success" ;
            }
        }
        return "error" ;
    }

执行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-obkqzByB-1585559126703)(C:\Users\333\AppData\Roaming\Typora\typora-user-images\1585558871749.png)]

2.5.2 SpringMVC方式上传

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript" src="static/jquery-3.4.1.js"></script>

</head>
<body>

    <input type="text" name="name" id="n">
    <input type="file"  id="file">
    <input type="button" value="获取" id="mybutton" >


    <script type="text/javascript" >
        $(function(){
            //点击事件
           $("#mybutton").click(function(){
               //获取name参数的值
               var $name = $("#n").val();
               //获取文件数组
               var file = document.getElementById("file").files ;
               var formData = new FormData();
               //name参数添加到formData中
               formData.append("name",$name) ;
               //获取文件数组中的一个元素,并添加到formData中
               formData.append("multipartFile",file[0]) ;
               //Ajax异步访问服务器
               $.post({
                   url:"test/json" ,
                   data: formData ,
                   contentType:false , //contentType不做处理,使用formData默认的multipart/form-data
                   processData: false , //使数据不做处理
                   //回调函数
                   success: function(result){
                       if (result=="success") {
                           alert("上传成功");
                       }else {
                           alert("上传失败");   
                       }
                       
                   }
               });

           });
        });
    </script>

</body>
</html>
	@ResponseBody
    @RequestMapping(value = "/json" ,method = RequestMethod.POST)
    public String  json(@RequestParam("name")String name ,
                        MultipartFile multipartFile ,
                        HttpServletRequest request) throws Exception {
        //获取项目的绝对路径+/upLoad/
        String path = request.getSession().getServletContext().getRealPath("/upLoad/");
        //控制打印项目真实地址
        System.out.println(path);
        File file = new File(path);
        //判断文件夹是否存在
        if (!file.exists()) {
            //创建文件夹
            file.mkdirs();
        }
        //控制台打印测试name参数
        if (name!=null)
            System.out.println(name);
        if (multipartFile!=null){
            //获取文件名
            String fileName = multipartFile.getOriginalFilename();
            //使用UUID定义唯一文件名
            String uuid = UUID.randomUUID().toString().replace("-", "");
            //上传文件
            multipartFile.transferTo(new File(file,uuid+"_"+fileName));
            //控制台打印测试
            System.out.println("上传成功");
            return "success" ;
        }
        return "error" ;

    }

执行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-geEadjRh-1585559126704)(C:\Users\333\AppData\Roaming\Typora\typora-user-images\1585558549539.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值