昨天下午在写一个上传的jsp标签,使用jquery uploadify 的flash版本。
这个jsp标签我之前写过一个servlet版本的,现在要将他改为springMVC版本的。本来以为移植过来会很容易,可是遇到了一个特别奇怪的问题,导致几乎一天的时间都在解决这个问题。
问题的描述如下:
按照官网的demo写完页面后,只要请求,控制台就会抛出异常: java.net.SocketException: Software caused connection abort: socket write error
这个异常出现的情形是:客户端发起了一个请求,服务端收到后,准备响应,但是还没有写回到客户端,该tcp连接就断了,于是服务端就会抛出该异常。
后来逐句删除,发现是 :
'swf' : '${path}/static/plugin/uploadify/flash/uploadify.swf',
这一句的问题,如果去掉,就不会出现该异常。
我之前servlet版本并没有这个问题,为什么这次会有?
一步步追踪错误,发现,原来项目中配置了 500的错误页面,导向到的错误页面中,会将该异常信息打印出来。
但这个异常是怎么形成的呢?
经过半天的调试,最后发现,在chrome浏览器中, 这个flash文件,即uploadify.swf 会被请求三次,
而前两次都是 canceled 只有第三次才是正常响应的。
于是,前两次的请求,服务端都会出现这个异常。
后来搜了一下,uploadify的确有人提出过这个问题。我访问官网,官网的demo页面也是请求了两次。
按照一篇帖子中提到的,看了一下源码:
var $wrapper = $('<div />', {
'id' : settings.id,
'class' : 'uploadify',
'css' : {
'height' : settings.height + 'px',
'width' : settings.width + 'px'
}
});
$('#' + swfuploadify.movieName).wrap($wrapper);
和
$('#' + swfuploadify.movieName).css({
'position' : 'absolute',
'z-index' : 1
});
这两个地方,分别发出一次请求,而这两次请求并没有完成响应就断掉了。
其实这两段代码的作用 就是 设置宽度和高度,然后在设置这个flash的 zindex。
于是按照网上说的,将这两段注释掉。然后
SWFUpload.prototype.getFlashHTML=function(){return['<div id="',this.settings.id,'" class="uploadify" style="height: ',this.settings.height,'px; width: ',this.settings.width,'px;" > <object style="position: absolute; z-index: 1" id="',this.movieName,'" type="application/x-shockwave-flash" data="',this.settings.flash_url,'" width="',this.settings.button_width,'" height="',this.settings.button_height,'" class="swfupload">','<param name="wmode" value="',this.settings.button_window_mode,'" />','<param name="movie" value="',this.settings.flash_url,'" />','<param name="quality" value="high" />','<param name="menu" value="false" />','<param name="allowScriptAccess" value="always" />','<param name="flashvars" value="'+this.getFlashVars()+'" />',"</object></div>"].join("")};
将getFlashHTML 方法最外层包裹一层div。
其实思路就是,手动将flash的设置位置的代码,从 单独的方法,提到 getFlashHTML中
修改完成后,再试,错误消失。