前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >XMLRequest在请求过程中处理返回的数据

XMLRequest在请求过程中处理返回的数据

作者头像
每天学Java
发布2020-06-02 10:06:06
1.1K0
发布2020-06-02 10:06:06
举报
文章被收录于专栏:每天学Java每天学Java

在前后端分离的项目中,我们前端会请求后端的接口,当请求结束后后将返回的数据展示到界面上,但是在后台的一些数据的批处理中,可能会比较耗时,此时我们可能需要知道后台的处理进度,但是使用JQuery的ajax请求会在请求完成时才会将数据展示success回调函数中。

01

思路描述

一开始的时候,我一直以为如果要实现这样一个功能应该十分费劲(也有可能是我先在实现的方式并不正规),我一直在考虑后台的相关修改,比如长连接,Session等等,类似于推送的实现,但是一直没有实现想要的效果,后来网上找到关于XMLRequest对象的readyState描述,当readyState等于3的时候所有响应头部都已经接收到,响应体开始接收但未完成。于是我就想到XMLRequest对象是否可以通过判断readyState来接受数据并进行数据的渲染呢?最终确实实现了,效果如下视频:弹出框会描述后台的工作状态,当然这也需要后台配合

02

实现方式

首先我们看前端实现代码,最开始的时候想使用Jquery的Ajax,但是我并没有发现它能够捕获到这个readyState值,所以这里我自己去利用XMLRequest对象去调用接口,当xmlhttp.readyState == 3的时候在页面上渲染

后端的实现就比较简单了,out.flush()的作用是:flush()立即将缓冲区的数据输出到接收方,也就是说每一次循环都会将数据输出到前端。

如果你使用Spring Boot写接口我们同样可以使用上面的代码来达到相同的效果:

到这里就达到上面视频的效果了,核心的代码我在文章的最后展示了,如果大家想复制下载,可以进入小程序中获取。

详细代码:

代码语言:javascript
复制
jQuery(document).ready(function () {
        function httpRequest(paramObj, fun, errFun) {
            var xmlhttp = null;
            /*创建XMLHttpRequest对象,
             *老版本的 Internet Explorer(IE5 和 IE6)使用 ActiveX 对象:new ActiveXObject("Microsoft.XMLHTTP")
             * */
            if (window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
            } else if (window.ActiveXObject) {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            /*判断是否支持请求*/
            if (xmlhttp == null) {
                alert('你的浏览器不支持XMLHttp');
                return;
            }
            /*请求方式,并且转换为大写*/
            var httpType = (paramObj.type || 'GET').toUpperCase();
            /*数据类型*/
            var dataType = paramObj.dataType || 'json';
            /*请求接口*/
            var httpUrl = paramObj.httpUrl || '';
            /*是否异步请求*/
            var async = paramObj.async || true;
            /*请求参数--post请求参数格式为:foo=bar&lorem=ipsum*/
            var paramData = paramObj.data || [];
            var requestData = '';
            for (var name in paramData) {
                requestData += name + '=' + paramData[name] + '&';
            }
            requestData = requestData == '' ? '' : requestData.substring(0, requestData.length - 1);
            console.log(requestData)
            /*请求接收*/
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 3) {
                    /*传输中*/
                    $("#content").html(xmlhttp.responseText)
                }
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    /*成功回调函数*/
                    fun(xmlhttp.responseText);
                } else {
                    /*失败回调函数*/
                    errFun;
                }
            }
            /*接口连接,先判断连接类型是post还是get*/
            if (httpType == 'GET') {
                xmlhttp.open("GET", httpUrl, async);
                xmlhttp.send(null);
            } else if (httpType == 'POST') {
                xmlhttp.open("POST", httpUrl, async);
                //发送合适的请求头信息
                xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                xmlhttp.send(requestData);
            }
        }

        /*请求参数*/
        var paramObj = {
            httpUrl: '/batch',
            type: 'post',
            data: {
                name: 'sss',
                sex: '男'
            }
        }
        /*请求调用*/
        httpRequest(paramObj, function (respondDada) {
            //这里编写成功的回调函数
            console.log(respondDada)
        }, function () {
            alert('网络错误')
        });
    })

后端代码:

代码语言:javascript
复制
package support.servlet;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @Auther: chenlong
 * @Date: 2019/2/21 20:18
 * @Description:
 */
public class Batch extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        doPost(req, res);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        res.setHeader("Content-type", "text/html;charset=UTF-8");
        //这句话的意思,是告诉servlet用UTF-8转码,而不是用默认的ISO8859
        PrintWriter out = res.getWriter();
        out.println("<div>批处理进行中...</div>");
        for (int i = 1; i < 23; i++)
            try {
                if (i == 2 || i == 3 || i == 6) {
                    out.println("<div style='display: flex; flex-direction: row;align-items: center;justify-content: center;'><div>第" + i + "个接口已经检查,需更新</div><button  style='border: 1px solid #0782e4; border-radius: 3px; margin-top: 5px; padding: 5px;  width: 50px;color:red'>更新</button></div>");
                } else {
                    out.println("<div>第" + i + "个接口已经检查,无需更新</div>");
                }
                out.flush();
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 每天学Java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档