SpringMVC中Ajax异步上传图片的方法
来源:互联网 发布:淘宝客 开源 编辑:程序博客网 时间:2024/06/05 19:51
项目中遇到了上传图片的需求,最开始用的是传统的同步上传,在需要上传图片的地方定义iframe,如下
<iframe id="uploadImg" frameborder=0 width=300 height=100 marginheight=0
marginwidth=0 scrolling=no src="jump_image_upload.xhtml">
</iframe>
这里的src通过Controller将iframe内容扭转至image_upload页,再到该页定义file控件进行图片上传。
这样会带来一个问题,即浏览器不兼容,提交后的样式在ie下面不可控,因此需要将同步上传改为异步上传,上网找了一些插件,最终发现ajaxfileupload.js比较好用,使用步骤如下:
1)下载ajaxfileupload.js,放到项目工程里面,前端页面使用如下:
$(".uploadBtn").click(function() {
$.ajaxFileUpload({
url : 'image_upload.json', //需要链接到服务器地址
beforeSend:function(){$(".progress").show();},
secureuri : false,
fileElementId : 'uploadFile', //文件选择框的id属性
dataType : 'json', //服务器返回的格式,可以是json
success : function(data, status) //相当于java中try语句块的用法
{
},
error : function(data, status, e) //相当于java中catch语句块的用法
{
}
});
});
2)后台代码如下:
@RequestMapping(value = "image_upload.json", method = RequestMethod.POST)
public void upload(@RequestParam(value="uploadFile")MultipartFile file,HttpServletRequest request,HttpServletResponse response) throws IOException
{
Map<String,String> model = new HashMap<String, String>();
String fileName = this.generateFileName(file.getOriginalFilename());
String path = request.getSession().getServletContext().getRealPath("upload");
File targetFile = this.imageUploadService.getTargetFile(path,fileName);
try
{
file.transferTo(targetFile);
this.imageUploadService.uploadImage(fileName, targetFile.getPath());
model.put("fileUrl", request.getContextPath() + "/upload/" + fileName);
model.put("file", fileName);
}
catch (Exception e)
{
logger.error("图片上传失败!", e);
model.put("errorMsg", "图片上传失败!");
}
JSONObject json = JSONObject.fromObject(model);
response.getWriter().write(json.toString());
response.getWriter().close();
}
最开始使用时,出现了一些问题,据说该插件针对jquery1.7+版本支持不好,如下:
(1)控制台提示少handerError方法;
具体解决方法是:上网找一个handlerError方法,添加到ajaxfileupload.js中。
(2)后台上传成功,但js总跳转到error逻辑;
具体解决办法:eval对data的处理有问题,将uploadHttpData方法中的eval( "data = " + $(data).html() ); 改为eval( "data = " + $(data).html() );
(3)IE浏览器下文件上传成功之后,总提示下载json数据
具体原因:针对异步上传文件的请求,Controller后台不能通过ResponseBody的方式返回json对象,而是要在后台组装成json数据格式,然后通过response对象write到前端页面。
(4)IE和Firefox、chrome浏览器不兼容
具体原因:response后台在write出前端页面的json数据时,不要设置contentType,之前我设置了:
response.setContentType("text/html;charset=UTF-8");
结果Firefox、chrome不正常,但IE正常;
后来设置了
response.setContentType("application/json;charset=UTF-8");
结果IE不正常,但Firefox、Chrome正常。
(5)文件上传一次之后,不刷新页面再次上传同一个文件,提示 上传失败
具体原因:文件上传时没有重命名,导致 file.transferTo(targetFile);这句出异常,每次上传时将图片按时间重命名就ok了。
一个能够正常运行的ajaxFileUpload.js全文如下:
jQuery.extend({
handleError: function( s, xhr, status, e ) {
// If a local callback was specified, fire it
if ( s.error ) {
s.error.call( s.context || s, xhr, status, e );
}
// Fire the global callback
if ( s.global ) {
(s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
}
},
createUploadIframe: function(id, uri)
{
var frameId = 'jUploadFrame' + id;
if(window.ActiveXObject) {
if(jQuery.browser.version=="9.0")
{
io = document.createElement('iframe');
io.id = frameId;
io.name = frameId;
}
else if(jQuery.browser.version=="6.0" || jQuery.browser.version=="7.0" || jQuery.browser.version=="8.0")
{
var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '" />');
if(typeof uri== 'boolean'){
io.src = 'javascript:false';
}
else if(typeof uri== 'string'){
io.src = uri;
}
}
}
else {
var io = document.createElement('iframe');
io.id = frameId;
io.name = frameId;
}
io.style.position = 'absolute';
io.style.top = '-1000px';
io.style.left = '-1000px';
document.body.appendChild(io);
return io;
},
ajaxUpload:function(s,xml){
//if((fromFiles.nodeType&&!((fileList=fromFiles.files)&&fileList[0].name)))
var uid = new Date().getTime(),idIO='jUploadFrame'+uid,_this=this;
var jIO=$('<iframe name="'+idIO+'" id="'+idIO+'" style="display:none">').appendTo('body');
var jForm=$('<form action="'+s.url+'" target="'+idIO+'" method="post" enctype="multipart/form-data"></form>').appendTo('body');
var oldElement = $('#'+s.fileElementId);
var newElement = $(oldElement).clone();
$(oldElement).attr('id', 'jUploadFile'+uid);
$(oldElement).before(newElement);
$(oldElement).appendTo(jForm);
this.remove=function()
{
if(_this!==null)
{
jNewFile.before(jOldFile).remove();
jIO.remove();jForm.remove();
_this=null;
}
}
this.onLoad=function(){
var data=$(jIO[0].contentWindow.document.body).text();
try{
if(data!=undefined){
data = eval('(' + data + ')');
try {
if (s.success)
s.success(data, status);
// Fire the global callback
if(s.global)
jQuery.event.trigger("ajaxSuccess", [xml, s]);
if (s.complete)
s.complete(data, status);
xml = null;
} catch(e)
{
status = "error";
jQuery.handleError(s, xml, status, e);
}
// The request was completed
if(s.global)
jQuery.event.trigger( "ajaxComplete", [xml, s] );
// Handle the global AJAX counter
if (s.global && ! --jQuery.active )
jQuery.event.trigger("ajaxStop");
// Process result
}
}catch(ex){
alert(ex.message);
};
}
this.start=function(){jForm.submit();jIO.load(_this.onLoad);};
return this;
},
createUploadForm: function(id, url,fileElementId, data)
{
//create form
var formId = 'jUploadForm' + id;
var fileId = 'jUploadFile' + id;
var form = jQuery('<form action="'+url+'" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
if(data)
{
for(var i in data)
{
jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);
}
}
var oldElement = jQuery('#' + fileElementId);
var newElement = jQuery(oldElement).clone();
jQuery(oldElement).attr('id', fileId);
jQuery(oldElement).before(newElement);
jQuery(oldElement).appendTo(form);
//set attributes
jQuery(form).css('position', 'absolute');
jQuery(form).css('top', '-1200px');
jQuery(form).css('left', '-1200px');
jQuery(form).appendTo('body');
return form;
},
ajaxFileUpload: function(s) {
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
// Create the request object
var xml = {};
s = jQuery.extend({}, jQuery.ajaxSettings, s);
if(window.ActiveXObject){
var upload = new jQuery.ajaxUpload(s,xml);
upload.start();
}else{
var id = new Date().getTime();
var form = jQuery.createUploadForm(id,s.url, s.fileElementId, (typeof(s.data)=='undefined'?false:s.data));
var io = jQuery.createUploadIframe(id, s.secureuri);
var frameId = 'jUploadFrame' + id;
var formId = 'jUploadForm' + id;
// Watch for a new set of requests
if ( s.global && ! jQuery.active++ )
{
jQuery.event.trigger( "ajaxStart" );
}
var requestDone = false;
if ( s.global )
jQuery.event.trigger("ajaxSend", [xml, s]);
// Wait for a response to come back
var uploadCallback = function(isTimeout)
{
var io = document.getElementById(frameId);
try
{
if(io.contentWindow)
{
xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;
xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;
}else if(io.contentDocument)
{
xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;
xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;
}
}catch(e)
{
jQuery.handleError(s, xml, null, e);
}
if ( xml || isTimeout == "timeout")
{
requestDone = true;
var status;
try {
status = isTimeout != "timeout" ? "success" : "error";
// Make sure that the request was successful or notmodified
if ( status != "error" )
{
// process the data (runs the xml through httpData regardless of callback)
var data = jQuery.uploadHttpData(xml, s.dataType);
// If a local callback was specified, fire it and pass it the data
if (s.success)
s.success(data, status);
// Fire the global callback
if(s.global)
jQuery.event.trigger("ajaxSuccess", [xml, s]);
if (s.complete)
s.complete(data, status);
} else
jQuery.handleError(s, xml, status);
} catch(e)
{
status = "error";
jQuery.handleError(s, xml, status, e);
}
// The request was completed
if(s.global)
jQuery.event.trigger( "ajaxComplete", [xml, s] );
// Handle the global AJAX counter
if (s.global && ! --jQuery.active )
jQuery.event.trigger("ajaxStop");
// Process result
jQuery(io).unbind();
setTimeout(function()
{ try
{
jQuery(io).remove();
jQuery(form).remove();
} catch(e)
{
jQuery.handleError(s, xml, null, e);
}
}, 100);
xml = null;
}
};
// Timeout checker
if (s.timeout>0)
{
setTimeout(function(){
// Check to see if the request is still happening
if( !requestDone ) uploadCallback("timeout");
}, s.timeout);
}
try
{
var form = jQuery('#' + formId);
jQuery(form).attr('action', s.url);
jQuery(form).attr('method', 'POST');
jQuery(form).attr('target', frameId);
if(form.encoding)
{
jQuery(form).attr('encoding', 'multipart/form-data');
}
else
{
jQuery(form).attr('enctype', 'multipart/form-data');
}
jQuery(form).submit();
} catch(e)
{
jQuery.handleError(s, xml, null, e);
}
jQuery('#'+ frameId).load(uploadCallback);
return {abort: function () {}};
}
},
uploadHttpData: function( r, type ) {
var data = !type;
data = type == "xml" || data ? r.responseXML : r.responseText;
// If the type is "script", eval it in global context
if ( type == "script" )
jQuery.globalEval( data );
// Get the JavaScript object, if JSON is used.
if ( type == "json" ){
eval( "data = " + $(data).html() );
}
// evaluate scripts within html
if ( type == "html" )
jQuery("<div>").html(data).evalScripts();
return data;
}
});
- SpringMVC中Ajax异步上传图片的方法
- 使用Ajax异步上传图片的方法(html,javascript,php)
- springmvc下使用formdata异步ajax上传图片
- SpringMVC+Ajax异步上传图片并显示(源码)
- ajax异步上传图片
- ajax异步上传图片
- ajax异步上传图片
- ajax异步上传图片
- SpringMVC AJAX异步文件上传
- springmvc 文件上传,图片上传的方法
- SpringMVC异步上传图片总结
- ajax图片上传,图片异步上传,更新
- ajax图片上传,图片异步上传,更新
- ThinkPHP 图片上传 图片异步上传 ajax
- ajax异步上传文件/图片
- Ajax实现异步上传图片
- ajax异步上传文件图片
- Ajax+PHP 异步上传图片
- 【OpenCV】邻域滤波:方框、高斯、中值、双边滤波
- pat 1001 A+B Format
- Android中ViewStub的使用
- 使用selector和shape实现圆角选项
- jdk之间的转换
- SpringMVC中Ajax异步上传图片的方法
- c和指针阅读笔记
- Ajax中Get请求与Post请求的区别
- AE新手基础入门教程50套从新手到高手
- 分析oracle索引空间使用情况,以及索引是否需要重建
- 在WPF中把Canvas保存为图片,文本文件,xps文件
- java 内存溢出解决方案
- [SPOJ VLATTICE]Visible Lattice Points 数论 莫比乌斯反演
- Mysql INSERT、REPLACE、UPDATE的区别