zoukankan      html  css  js  c++  java
  • JS代码中加上alert才能正常显示效果

      模拟一个生成验证码的效果,发现JS代码中加上alert可以正常刷新,没有alert时图片就会丢失,找到解决方法,但是还不是很明白,先记录下来。

          生成验证码的servlet代码如下:

    package servlet;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    import javax.imageio.ImageIO;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    /**
     * 生成随机图片,用来作为验证码
     */
    public class DrawImage extends HttpServlet {
        private static final long serialVersionUID = 3038623696184546092L;
        
        public static final int WIDTH = 120;//生成的图片的宽度
        public static final int HEIGHT = 30;//生成的图片的高度
    
        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            this.doPost(request, response);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            String createTypeFlag = request.getParameter("createTypeFlag");//接收客户端传递的createTypeFlag标识
            //1.在内存中创建一张图片
            BufferedImage bi = new BufferedImage(WIDTH, HEIGHT,BufferedImage.TYPE_INT_RGB);
            //2.得到图片
            Graphics g = bi.getGraphics();
            //3.设置图片的背影色
            setBackGround(g);
            //4.设置图片的边框
            setBorder(g);
            //5.在图片上画干扰线
            drawRandomLine(g);
            //6.写在图片上随机数
            //String random = drawRandomNum((Graphics2D) g,"ch");//生成中文验证码图片
            //String random = drawRandomNum((Graphics2D) g,"nl");//生成数字和字母组合的验证码图片
            //String random = drawRandomNum((Graphics2D) g,"n");//生成纯数字的验证码图片
            //String random = drawRandomNum((Graphics2D) g,"l");//生成纯字母的验证码图片
            String random = drawRandomNum((Graphics2D) g,createTypeFlag);//根据客户端传递的createTypeFlag标识生成验证码图片
            //7.将随机数存在session中
            request.getSession().setAttribute("checkcode", random);
            //8.设置响应头通知浏览器以图片的形式打开
            response.setContentType("image/jpeg");//等同于response.setHeader("Content-Type", "image/jpeg");
            //9.设置响应头控制浏览器不要缓存
            response.setDateHeader("expries", -1);
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Pragma", "no-cache");
            //10.将图片写给浏览器
            ImageIO.write(bi, "jpg", response.getOutputStream());
        }
    
        /**
         * 设置图片的背景色
         * @param g
         */
        private void setBackGround(Graphics g) {
            // 设置颜色
            g.setColor(Color.WHITE);
            // 填充区域
            g.fillRect(0, 0, WIDTH, HEIGHT);
        }
    
        /**
         * 设置图片的边框
         * @param g
         */
        private void setBorder(Graphics g) {
            // 设置边框颜色
            g.setColor(Color.BLUE);
            // 边框区域
            g.drawRect(1, 1, WIDTH - 2, HEIGHT - 2);
        }
    
        /**
         * 在图片上画随机线条
         * @param g
         */
        private void drawRandomLine(Graphics g) {
            // 设置颜色
            g.setColor(Color.GREEN);
            // 设置线条个数并画线
            for (int i = 0; i < 5; i++) {
                int x1 = new Random().nextInt(WIDTH);
                int y1 = new Random().nextInt(HEIGHT);
                int x2 = new Random().nextInt(WIDTH);
                int y2 = new Random().nextInt(HEIGHT);
                g.drawLine(x1, y1, x2, y2);
            }
        }
    
        /**
         * 画随机字符
         * @param g
         * @param createTypeFlag
         * @return
         * String... createTypeFlag是可变参数,
         * Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。注意:可变参数必须位于最后一项
         */
        private String drawRandomNum(Graphics2D g,String... createTypeFlag) {
            // 设置颜色
            g.setColor(Color.RED);
            // 设置字体
            g.setFont(new Font("宋体", Font.BOLD, 20));
            //常用的中国汉字
            String baseChineseChar = "u7684u4e00u4e86u662fu6211u4e0du5728u4ebau4eecu6709u6765u4ed6u8fd9u4e0au7740u4e2au5730u5230u5927u91ccu8bf4u5c31u53bbu5b50u5f97u4e5fu548cu90a3u8981u4e0bu770bu5929u65f6u8fc7u51fau5c0fu4e48u8d77u4f60u90fdu628au597du8fd8u591au6ca1u4e3au53c8u53efu5bb6u5b66u53eau4ee5u4e3bu4f1au6837u5e74u60f3u751fu540cu8001u4e2du5341u4eceu81eau9762u524du5934u9053u5b83u540eu7136u8d70u5f88u50cfu89c1u4e24u7528u5979u56fdu52a8u8fdbu6210u56deu4ec0u8fb9u4f5cu5bf9u5f00u800cu5df1u4e9bu73b0u5c71u6c11u5019u7ecfu53d1u5de5u5411u4e8bu547du7ed9u957fu6c34u51e0u4e49u4e09u58f0u4e8eu9ad8u624bu77e5u7406u773cu5fd7u70b9u5fc3u6218u4e8cu95eeu4f46u8eabu65b9u5b9eu5403u505au53ebu5f53u4f4fu542cu9769u6253u5462u771fu5168u624du56dbu5df2u6240u654cu4e4bu6700u5149u4ea7u60c5u8defu5206u603bu6761u767du8bddu4e1cu5e2du6b21u4eb2u5982u88abu82b1u53e3u653eu513fu5e38u6c14u4e94u7b2cu4f7fu5199u519bu5427u6587u8fd0u518du679cu600eu5b9au8bb8u5febu660eu884cu56e0u522bu98deu5916u6811u7269u6d3bu90e8u95e8u65e0u5f80u8239u671bu65b0u5e26u961fu5148u529bu5b8cu5374u7ad9u4ee3u5458u673au66f4u4e5du60a8u6bcfu98ceu7ea7u8ddfu7b11u554au5b69u4e07u5c11u76f4u610fu591cu6bd4u9636u8fdeu8f66u91cdu4fbfu6597u9a6cu54eau5316u592au6307u53d8u793eu4f3cu58ebu8005u5e72u77f3u6ee1u65e5u51b3u767eu539fu62ffu7fa4u7a76u5404u516du672cu601du89e3u7acbu6cb3u6751u516bu96beu65e9u8bbau5417u6839u5171u8ba9u76f8u7814u4ecau5176u4e66u5750u63a5u5e94u5173u4fe1u89c9u6b65u53cdu5904u8bb0u5c06u5343u627eu4e89u9886u6216u5e08u7ed3u5757u8dd1u8c01u8349u8d8au5b57u52a0u811au7d27u7231u7b49u4e60u9635u6015u6708u9752u534au706bu6cd5u9898u5efau8d76u4f4du5531u6d77u4e03u5973u4efbu4ef6u611fu51c6u5f20u56e2u5c4bu79bbu8272u8138u7247u79d1u5012u775bu5229u4e16u521au4e14u7531u9001u5207u661fu5bfcu665au8868u591fu6574u8ba4u54cdu96eau6d41u672au573au8be5u5e76u5e95u6df1u523bu5e73u4f1fu5fd9u63d0u786eu8fd1u4eaeu8f7bu8bb2u519cu53e4u9ed1u544au754cu62c9u540du5440u571fu6e05u9633u7167u529eu53f2u6539u5386u8f6cu753bu9020u5634u6b64u6cbbu5317u5fc5u670du96e8u7a7fu5185u8bc6u9a8cu4f20u4e1au83dcu722cu7761u5174u5f62u91cfu54b1u89c2u82e6u4f53u4f17u901au51b2u5408u7834u53cbu5ea6u672fu996du516cu65c1u623fu6781u5357u67aau8bfbu6c99u5c81u7ebfu91ceu575au7a7au6536u7b97u81f3u653fu57ceu52b3u843du94b1u7279u56f4u5f1fu80dcu6559u70edu5c55u5305u6b4cu7c7bu6e10u5f3au6570u4e61u547cu6027u97f3u7b54u54e5u9645u65e7u795eu5ea7u7ae0u5e2eu5566u53d7u7cfbu4ee4u8df3u975eu4f55u725bu53d6u5165u5cb8u6562u6389u5ffdu79cdu88c5u9876u6025u6797u505cu606fu53e5u533au8863u822cu62a5u53f6u538bu6162u53d4u80ccu7ec6";
            //数字和字母的组合
            String baseNumLetter = "0123456789ABCDEFGHJKLMNOPQRSTUVWXYZ";
            //纯数字
            String baseNum = "0123456789";
            //纯字母
            String baseLetter = "ABCDEFGHJKLMNOPQRSTUVWXYZ";
            //createTypeFlag[0]==null表示没有传递参数
            if (createTypeFlag.length > 0 && null != createTypeFlag[0]) {
                if (createTypeFlag[0].equals("ch")) {
                    // 截取汉字
                    return createRandomChar(g, baseChineseChar);
                }else if (createTypeFlag[0].equals("nl")) {
                    // 截取数字和字母的组合
                    return createRandomChar(g, baseNumLetter);
                }else if (createTypeFlag[0].equals("n")) {
                    // 截取数字
                    return createRandomChar(g, baseNum);
                }else if (createTypeFlag[0].equals("l")) {
                    // 截取字母
                    return createRandomChar(g, baseLetter);
                }
            }else {
                // 默认截取数字和字母的组合
                return createRandomChar(g, baseNumLetter);
            }
            
            return "";
        }
    
        /**
         * 创建随机字符
         * @param g
         * @param baseChar
         * @return 随机字符
         */
        private String createRandomChar(Graphics2D g,String baseChar) {
            StringBuffer sb = new StringBuffer();
            int x = 5;
            String ch ="";
            // 控制字数
            for (int i = 0; i < 4; i++) {
                // 设置字体旋转角度
                int degree = new Random().nextInt() % 30;
                ch = baseChar.charAt(new Random().nextInt(baseChar.length())) + "";
                sb.append(ch);
                // 正向角度
                g.rotate(degree * Math.PI / 180, x, 20);
                g.drawString(ch, x, 20);
                // 反向角度
                g.rotate(-degree * Math.PI / 180, x, 20);
                x += 30;
            }
            return sb.toString();
        }
    }
    

      JSP的代码如下:

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>在Form表单中使用验证码</title>
        <script type="text/javascript">
        //刷新验证码
        function changeImg(){
            var img = document.getElementById("validateCodeImg");
            img.src= "<%=request.getContextPath()%>/servlet/drawImage?"+Math.random();
        }
        </script>
      </head>
      
      <body>
            <form action="${pageContext.request.contextPath}/servlet/CheckServlet" method="post">
                验证码:<input type="text" name="validateCode"/>
                <img alt="验证码看不清,换一张" src="<%=request.getContextPath()%>/servlet/drawImage" id="validateCodeImg" onclick="changeImg()">
                <a href="javascript:void(0)" onclick="changeImg()">看不清,换一张</a>
                <br/>
                <input type="submit" value="提交">
            </form>
      </body>
    </html>
    

      网上查到的解释如下:   

      JS是单进程的(浏览器是多进程的但JS不是)
      程序运行到alert()就停止了,后面的你不点就不运行,
      而且JS有阻塞特性,遇到alert() conform() 这类的,浏览器的渲染也会停止。代码之后的JS不会执行,之后的节点也不会被显示,就是浏览器除非得到用户响应,否则什么也不做了,死等。这就是JS的阻塞特性。

        

        另外一种解释:

      问题: 

            我是做一个回车事件处理,翻页的那种,在一个页面上成功了,换到另外两个页面上就出错了。反正就是跳到1,如果加上alert(),就跳转成功。

      可能情况:

             这种情况一般出现在 alert() 之后的某个代码需要页面元素进入一定的状态才能使用,加上 alert() 之后,相当于页面元素有足够的时间进入一定的状态了,如果确定你的代  码没有问题,你可以把 alert() 之后的代码放到一个 setTimeout 的函数中,也就是停一会再运行下面的代码,应该就没问题了。

      思考如下,可能是生成验证码的过程较慢,具体的还不是很明白。

         解决办法:加上window.location.reload();

        <script type="text/javascript">
        //刷新验证码
        function changeImg(){
            var img = document.getElementById("validateCodeImg");
            img.src= "<%=request.getContextPath()%>/servlet/drawImage?"+Math.random();
            window.location.reload();
        }
        </script>
    

      

  • 相关阅读:
    C++笔记(2018/2/6)
    2017级面向对象程序设计寒假作业1
    谁是你的潜在朋友
    A1095 Cars on Campus (30)(30 分)
    A1083 List Grades (25)(25 分)
    A1075 PAT Judge (25)(25 分)
    A1012 The Best Rank (25)(25 分)
    1009 说反话 (20)(20 分)
    A1055 The World's Richest(25 分)
    A1025 PAT Ranking (25)(25 分)
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/4015856.html
Copyright © 2011-2022 走看看