您的位置:首页 > 其它

swfupload组件图片上传失败问题分析与总结

2015-09-15 14:28 295 查看
一、bug场景

部分浏览器图片上传失败。本人参与的系统广告系统A,使用A系统上传图片时,需要调用到B系统的图片api。

二、原因分析

可能原因1 :图片服务器api问题(No)

当时第一反应是,可能是公司图片服务器api的问题,因为图片api部署在多台服务器上,如果图片上传的请求刚好到达"坏掉"的api服务器,图片上传将会失败。但是运营人员抓取了图片api的日志,没有发现错误信息。后来,我们通过查看日志,发现每次调用图片api,都是返回正常状态码200。

上传文件结果----------{"code":200,"msg":"success","result"}


到此,我们觉得可能不是图片api问题,必须找其他原因。

可能原因2: 图片上传的请求到达广告系统的service层后,抛异常(No)

通过查看日志,发现部分图片上传的请求压根就没到达广告系统的service层。理由是,在某个时间点,运营人员通过谷歌浏览器发送图片上传的请求,但是在这个时间点上,并没有相关日志。正常情况下,广告系统是有记录日志进行跟踪的。

可能原因3:图片上传的请求没进入到广告系统的web层,就报错了。(Yes)

通过公司的日志工具查看access log得知,ip为xxx.xxx.xxx.xxx发送的图片上传请求,服务器返回400的状态码,也即是说,请求无效。到此,我们分析了导致这个问题的几种原因。

1、参数类型转换问题(No)

@RequestMapping(value = "/sourceUpload", method = RequestMethod.POST)
@ResponseBody
public String sourceUpload(@RequestParam(value = "myfiles") MultipartFile fileField,@RequestParam(value = "httpsFlag") StringhttpsFlag) {}


这是图片上传的web层接口,httpsFlag这个字段是String类型的,但是jsp传过来的是数字类型的,如:0,1,2,这样spring mvc会不会转换出错。其实不会的,虽然jsp传过来的是数字类型的,但是其实是以"1","2"字符串的形式传过来的,spring mvc是可以接收到的。

2、httpsFlag参数压根就没传过来。(Yes)

后来,我在本地启动广告系统,使用陆巧贤的浏览器进行远程debug,发现使用她的电脑,文件上传的请求payload中,是没有包含httpsFlag字段的,只有myfiles的,如下:

payload:

02版赠品02-700x500.jpg
------------Ij5cH2gL6ei4KM7KM7GI3gL6ei4cH2
Content-Disposition: form-data; name="myfiles"; filename="02版赠品02-700x500.jpg"
Content-Type: application/octet-stream


由于没有传过来httpsFlag这个参数,而spring mvc的接口又要求必须使用传入这个参数,最后导致请求到达spring mvc的拦截器后,由于匹配不到对应的action而抛出400的错误。现在的问题是,为何httpsFlag这个字段没有传递过来?

最后发现是因为开源上传组件swfupload的一个问题,如下:

this.setPostParams({
'httpsFlag':$('#httpsFlag').val()
});


swfupload使用上面的代码进行参数传递,但是参数名字必须使用双引号括住,如果使用单引号,部分浏览器会出现问题。把代码改成如下形式即可。

this.setPostParams({
"httpsFlag":$('#httpsFlag').val()
});


改完后,请求的payload中,终于出现了httpsFlag参数了。

payload:

330868-14030420415958.jpg
------------ae0ei4GI3Ij5gL6KM7ae0gL6cH2cH2
Content-Disposition: form-data; name="httpsFlag"
0
------------ae0ei4GI3Ij5gL6KM7ae0gL6cH2cH2
Content-Disposition: form-data; name="myfiles"; filename="330868-14030420415958.jpg"
Content-Type: application/octet-stream


总结:

1、 多使用公司提供的日志工具,帮助定位问题;

2、 每个请求,都会经过多个环节,一个环节一个环节的排除

3、 使用spring mvc定义web层接口参数时,可以加入required = false这个配置,这样的话,即使参数没有传递进来,仍然可以进入到action接口,然后我们可以在action中抛出相关信息,这样问题比较好定位;

4、 部分浏览器上传失败的根本原因目前还不清楚,可能是浏览器配置问题或者pc问题;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: