Code Bye

火狐浏览器请求动态图片,会发出两次请求

 
public class ImageServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private static int I_WIDTH = 60;
	private static int I_HEIGHT = 18;
	private static Font VALIDATECODE_FONT = new Font("Times New Roman",
			Font.PLAIN, 18);

	public ImageServlet() {
		super();
	}

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// 在内存中创建图象
		BufferedImage image = new BufferedImage(I_WIDTH, I_HEIGHT,
				BufferedImage.TYPE_INT_RGB);
		// 获取图形上下文
		Graphics g = image.getGraphics();
		// 设定背景色
		g.setColor(Color.white);
		g.fillRect(0, 0, I_WIDTH, I_HEIGHT);
		// 画边框
		g.setColor(Color.blue);
		g.drawRect(0, 0, I_WIDTH - 1, I_HEIGHT - 1);
		Long validate = new Long(10000 + Math.round((Math.random() * 90000)));
		String validateCode = validate.toString();
		request.getSession().setAttribute("validateCode", validateCode);
		// 将认证码显示到图象中
		g.setColor(Color.black);
		g.setFont(VALIDATECODE_FONT);
		// g.drawString(rand,10,15);
		g.drawString(validateCode.toString(), 7, 15);
		// 随机产生88个干扰点,使图象中的认证码不易被其它程序探测到
		Random random = new Random();
		for (int iIndex = 0; iIndex < 128; iIndex++) {
			int x = random.nextInt(I_WIDTH);
			int y = random.nextInt(I_HEIGHT);
			g.drawLine(x, y, x, y);
		}
		// 图象生效
		g.dispose();
		// 输出图象到页面
		ImageIO.write(image, "JPEG", response.getOutputStream());
		System.out.println("=============================================");
	}
}

以上为servlet代码,通过浏览器直接访问:http://localhost:8080/struts2/ImageServlet
在火狐浏览器上,测试会发出两次请求。
求教是什么原理。

我所使用的测试版本为:火狐25.0.

另外说明下,servlet代码为从网络随便找到的生成图片的代码。
引用 1 楼 xiuyuandashi 的回复:

另外说明下,servlet代码为从网络随便找到的生成图片的代码。

两次请求是什么意思呢?向servlet请求两次吗?不科学啊

我表示怀疑~~
引用 2 楼 magi1201 的回复:
Quote: 引用 1 楼 xiuyuandashi 的回复:

另外说明下,servlet代码为从网络随便找到的生成图片的代码。

两次请求是什么意思呢?向servlet请求两次吗?不科学啊

           从 输出看,是输出了两次。这个例子没有其他的依赖代码,很容易运行。可以试试看。

引用 3 楼 huxiweng 的回复:

我表示怀疑~~

        从 输出看,是执行了两次。这个例子没有其他的依赖代码,很容易运行。可以试试看。

补充下,servlet的配置为 /ImageServlet

10分
是有时候火狐会走两次doGet()方法,但也只生成一个验证码出来

想了一会儿,还没想到一个合理的解释的方法。

5分
en ,我也遇到过,如果是通过页面引用该servlet就不会出现调用两次的现象。。
引用 8 楼 ch656409110 的回复:

en ,我也遇到过,如果是通过页面引用该servlet就不会出现调用两次的现象。。

我猜测可能是浏览器在处理这个图片的时候,做了什么多余的动作。这个里面的道理我就猜不出了。

过来顶一下,希望有大牛过来解释下这个现象。
代码层面没问题,用其他浏览器试试看看。
还有就是把firefox的插件全部禁用试试

10分
引用 11 楼 huxiweng 的回复:

代码层面没问题,用其他浏览器试试看看。
还有就是把firefox的插件全部禁用试试

其它浏览器都没问题,火狐试10次,有8次都是走两次doGet,没有找到规律。但是向页面响应却是有一次,想不明白原因


5分
引用 12 楼 magi1201 的回复:
Quote: 引用 11 楼 huxiweng 的回复:

代码层面没问题,用其他浏览器试试看看。
还有就是把firefox的插件全部禁用试试

其它浏览器都没问题,火狐试10次,有8次都是走两次doGet,没有找到规律。但是向页面响应却是有一次,想不明白原因

插件问题

你就当浏览器bug吧。还好只是针对图片。要不然在网易宝里面充钱每次提交两次money就会翻番了。。
不太清楚,我记得之前好像也有人出现过这个问题

10分
 ImageIO.write(image, “JPEG”, response.getOutputStream());我一般不会这样写。

我一般会这样写。

ServletOutputStream sos = response.getOutputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();  
ImageIO.write(image, “JPEG”, bos);      
byte [] buf = bos.toByteArray();  
sos.write(buf);  
bos.close();  
sos.close(); 

引用 14 楼 ch656409110 的回复:

你就当浏览器bug吧。还好只是针对图片。要不然在网易宝里面充钱每次提交两次money就会翻番了。。

扣钱也会扣翻翻

引用 16 楼 fangmingshijie 的回复:

 ImageIO.write(image, “JPEG”, response.getOutputStream());我一般不会这样写。

我一般会这样写。

ServletOutputStream sos = response.getOutputStream();
ByteArrayOutputStream bos = new ByteArrayOutputStream();  
ImageIO.write(image, “JPEG”, bos);      
byte [] buf = bos.toByteArray();  
sos.write(buf);  
bos.close();  
sos.close(); 

貌似这样也会又问题。呵呵。

这个问题在3年遇到两次,个人认为就是火狐浏览器的问题
我刚也遇到过,是插件的问题,禁用了一些插件后,重启Firefox,问题解决了

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明火狐浏览器请求动态图片,会发出两次请求