最近做了个下载文件的功能,需要异常情况时后台直接返回浏览器弹窗,我就直接后台反回了弹窗的简单js脚本。但前端小火伴说太丑了,银行要求比较高,要美观大方,我说能实现,你讲吧。谁知,他又拉了个伙伴和UI设计,然后噼里啪啦给我讲了一大堆样式效果,听得我一肚子火。当时都周五了,再调样式,再给UI看效果,再给我们测试测,再给行方测,再加上建行的垃圾云桌面系统,卡的要死,大流程走下来,半天都不一定能完,那我周六岂不是要加班了?越想越不开心,就直接怼回去了,实现不了,就这样了!

  现在刚好周末有时间,就顺便琢磨测试了一下。

  之所以需要后台代码来实现弹窗效果修改,是因为前端点击完下载按钮后,此时已经不受前端发起人控制,后台将文件流读出返回浏览器,成功时调用浏览器的下载弹窗,失败时返回错误提示至浏览器。

  实现浏览器弹窗效果的修改,需要js中重写alrt方法,对于后台开发来说,也只是把前端的css、js代码搬到后台,返回页面上。其实,实现起来不难,但是把前端代码复制到java中,涉及到单双引号转换、转义,很容易在细节上出错,我就是在细节上出错,导致调了一下午才调好样式。

  下面介绍一下我琢磨测试的过程和效果:

    分三种情况:

             第一:简单型的,没有样式要求,浏览器自带的弹窗效果就可以满足的,直接alert即可。

             第二:样式写在css或js中,然后直接放到java字符串中。

             第三种:抽取了css、js到外文件夹下,此时需要引入css、js到java字符串中。

1、导出文件代码:

@RequestMapping("/exportExcel")
    public void exportFile(HttpServletRequest request, HttpServletResponse response){
        String filename = request.getParameter("fileName");
        DataInputStream in = null;
        OutputStream out = null;
        try{
            response.reset();// 清空输出流
            String resultFileName = "导出文件名" + System.currentTimeMillis() + ".xls";
            resultFileName = URLEncoder.encode(resultFileName,"UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-disposition", "attachment; filename=" + resultFileName);// 设定输出文件头
//            response.setContentType("application/msexcel");// 定义输出类型
            //输入流:本地文件路径
//            String contexPath= request.getSession().getServletContext().getRealPath("/") ;
            String contexPath ="D:\\A_WorkSpace\\decorate-furniture\\decorate_web\\src\\main\\resources\\1报名名单.xls";
//            String contexPath ="D:\\A_WorkSpace\\decorate-furniture\\decorate_web\\src\\main\\resources\\a配置说明.doc";
            in = new DataInputStream(new FileInputStream(new File(contexPath )));
            //输出流a
            out = response.getOutputStream();
            //输出文件
            int bytes = 0;
            byte[] bufferOut = new byte[1024];
            while ((bytes = in.read(bufferOut)) != -1) {
                out.write(bufferOut, 0, bytes);
            }
        } catch(Exception e){
            e.printStackTrace();
            response.reset();
            try {
                OutputStreamWriter writer = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
              String data = "<script language='javascript'>alert(\"\\u64cd\\u4f5c\\u5f02\\u5e38\\uff01\"); </script>";                                                              
                writer.write(data);
                writer.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }finally {
            if(null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

2、仅仅实现alert弹窗效果,不做样式的修改,代码中红色粗体部分:

    (1)代码所示:

String data = "<script language='javascript'>alert(\"\\u64cd\\u4f5c\\u5f02\\u5e38\\uff01\"); </script>";

    (2)弹窗效果图:

java登录成功 写入cookie_java登录成功 写入cookie

3、css、js未抽取时,代码中红色粗体部分::

    (1)代码:

String data = "<style type='text/css'>\n" +
        "    *{margin:0;padding:0;font-size:12px;}\n" +
        "    .ul{list-style:none;margin:0px;padding:0px;width:100%}\n" +
        "    .title{background:#F2F2F2;text-align:left;padding-left:20px;line-height:60px;border:1px solid #999;}\n" +
        "    .content{background:#D1E0F1;text-align:center;height:95px;line-height:95px;border-left:1px solid #999;border-right:1px solid #999;color:#F0F;}\n" +
        "    .btn-wrap{background:#F2F2F2;text-align:center;height:60px;line-height:25px; border:1px solid #999;}\n" +
        "    .btn{width:80px;height:40px;background:#999;margin-top:10px;border:1px solid #FFF;cursor:pointer;color:#333;}\n" +
        "    .btn:hover{color:#666;}\n" +
        "</style>"+
        "<script>"+
        "window.alert = function(str){\n" +
        "        var shield = document.createElement('DIV');\n" +
        "        document.body = document.createElement('BODY');\n" +
        "        document.body = document.createElement(\"BODY\");\n" +
        "        shield.id = 'shield';\n" +
        "        shield.style.position = 'absolute';\n" +
        "        shield.style.left = '50%';\n" +
        "        shield.style.top = '50%';\n" +
        "        shield.style.width = '300px';\n" +
        "        shield.style.height = '300px';\n" +
        "        shield.style.marginLeft = '-150px';\n" +
        "        shield.style.marginTop = '-150px';\n" +
        "        shield.style.zIndex = '25';\n" +
        "        var alertFram = document.createElement('DIV');\n" +
        "        alertFram.id='alertFram';\n" +
        "        alertFram.style.position = 'absolute';\n" +
        "        alertFram.style.width = '300px';\n" +
        "        alertFram.style.height = '200px';\n" +
        "        alertFram.style.left = '50%';\n" +
        "        alertFram.style.top = '0';\n" +
        "        alertFram.style.marginLeft = '-140px';\n" +
        "        alertFram.style.marginTop = '120px';\n" +
        "        alertFram.style.textAlign = 'center';\n" +
        "        alertFram.style.lineHeight = '150px';\n" +
        "        alertFram.style.zIndex = '300';\n" +
        "        strHtml = '<ul class=\"ul\"><li class=\"title\"><img src=\"http://127.0.0.1:8081/timg.jpg\" style=\"width: 40px;height: 40px\"></li><li class=\"content\">'+str+'</li><li class=\"btn-wrap\"><input type=\"button\" value=\"\\u786e\\u5b9a\" onclick=\"doOk()\" class=\"btn\"/></li></ul>';\n" +
        "        alertFram.innerHTML = strHtml;\n" +
        "        document.body.appendChild(alertFram);\n" +
        "        document.body.appendChild(shield);\n" +
        "        this.doOk = function(){ alertFram.style.display = 'none';  shield.style.display = 'none'; }\n" +
        "        alertFram.focus();\n" +
        "        document.body.onselectstart = function(){return false;};\n" +
        "    }\n" +
        "    alert('\\u64cd\\u4f5c\\u5f02\\u5e38\\uff01');"
        +"</script>";

    (2)效果

java登录成功 写入cookie_f5_02

4、css、js抽取出来通过路径引入方式实现,代码中红色粗体部分:

(1)data值为:

String data ="<head><link href='http://127.0.0.1:8081/style.css' rel='stylesheet' type='text/css'></head>"+
"<script>\n"+
"window.alert = function(str){\n" +
"        var shield = document.createElement('DIV');\n" +
"        document.body = document.createElement('BODY');\n" +
"        document.body = document.createElement(\"BODY\");\n" +
"        shield.id = 'shield';\n" +
"        shield.style.position = 'absolute';\n" +
"        shield.style.left = '50%';\n" +
"        shield.style.top = '50%';\n" +
"        shield.style.width = '300px';\n" +
"        shield.style.height = '300px';\n" +
"        shield.style.marginLeft = '-150px';\n" +
"        shield.style.marginTop = '-150px';\n" +
"        shield.style.zIndex = '25';\n" +
"        var alertFram = document.createElement('DIV');\n" +
"        alertFram.id='alertFram';\n" +
"        alertFram.style.position = 'absolute';\n" +
"        alertFram.style.width = '300px';\n" +
"        alertFram.style.height = '200px';\n" +
"        alertFram.style.left = '50%';\n" +
"        alertFram.style.top = '0';\n" +
"        alertFram.style.marginLeft = '-140px';\n" +
"        alertFram.style.marginTop = '120px';\n" +
"        alertFram.style.textAlign = 'center';\n" +
"        alertFram.style.lineHeight = '150px';\n" +
"        alertFram.style.zIndex = '300';\n" +
"        strHtml = '<ul class=\"ul\"><li class=\"title\"><img src=\"http://127.0.0.1:8081/yellow.png\" style=\"width: 40px;height: 40px\"></li><li class=\"content\">'+str+'</li><li class=\"btn-wrap\"><input type=\"button\" value=\"\\u786e\\u5b9a\" onclick=\"doOk()\" class=\"btn\"/></li></ul>';\n" +
"        alertFram.innerHTML = strHtml;\n" +
"        document.body.appendChild(alertFram);\n" +
"        document.body.appendChild(shield);\n" +
"        this.doOk = function(){ alertFram.style.display = 'none';  shield.style.display = 'none'; }\n" +
"        alertFram.focus();\n" +
"        document.body.onselectstart = function(){return false;};\n" +
"    }\n" +
"    alert('\\u64cd\\u4f5c\\u5f02\\u5e38\\uff01');"
+"</script>";

(2)展示效果为:

java登录成功 写入cookie_java登录成功 写入cookie_03

在java的字符串中写css、js、html代码时,一定要细心,因为没有提醒,也很容易出错。

同样,该方式也适用于后台重写prompt、confirm样式。