需求背景:需求需要实现上传excel,做数据导入功能,故使用插件jquery.from.js,版本号为3.51.0。
项目环境:老项目=前台JSP+Struts2+JPA+Spring
问题描述:1兼容性问题:IE9以下版本,ajaxSubmit发送请求后,后台导入数据成功,前台没有执行ajaxSubmit的回调函数。
2表单重复提交问题:首次点击提交,后台处理一次请求;第二次点击提交,后台处理两次请求;第三次点击提交,后台处理三次请求,依次类推............
最新版本插件下载地址:https://github.com/jquery-form/form/blob/master/src/jquery.form.js
本文使用插件下载地址:https://download.csdn.net/download/itdevil/11648285
因被上述两个问题困扰很久,故各种百度文章,发现答案不一,有的因环境不同,并未能解决我的问题,所以写篇文章记录一下,当然也是参考各种已有的答案做的总结,初心只是想让需要帮助的人少走弯路。
前台JSP部分代码:
<form id="uploadexcel">
<div class="box-main">
<input type="file" name="importFile" id="importFile" style="width: 273px; height: 26px; border:1px solid #cccccc;" value="" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"/>
<!-- <button style="background:#feddd9;">选择文件</button> -->
</div>
<div class="box-footer">
<button class="button-left" onclick="javascript:submitexcelFile();">提交</button>
<button class="button-right" onclick="javascript:deleteUploadFile();">取消 </button>
</div>
</form>
这里需要注意的一点就是<input />标签中的name的名称要与后台定义的File类型的属性名保持一致。
JS代码:
function submitexcelFile()
{
//定义此标志位,防止表单重复提交
var flag=true;
$('#uploadexcel').submit(function() {
var optionss = {
dataType:"text/html",//服务器响应返回的数据类型
type:'post', //表单提交方式
url: '${ctx}/merchant/shop/importShopInfo!importShopInfo.json', //请求地址
enctype: 'multipart/form-data',//服务器响应返回的数据类型
beforeSubmit:showRequest,//提交前执行的回调函数
complete:showResponse,//提交后执行的回调函数
//async: false, //是否异步
clearForm:true, //表单提交成功后,是否清除表单数据
timeout:3000 //设置请求的超时时间
};
if(flag){
//提交表单
$(this).ajaxSubmit(optionss);
flag=false;
//防止表单重复提交,默认会提交一次,异步会提交一次
return false;
}
});
}
//导入成功的回调函数
function showResponse(data) {
data = JSON.parse(data.responseText);
var msgArr = eval(data);
if(msgArr.length>0){
var strConnect="";
for(var i in msgArr){
strConnect+=data[i]+"<br/>";
}
/* $('.pop').css('display', 'block'); */
$('.pop').html(strConnect);
$('.modal-pop').show();
}else{
window.location.reload();
}
//alert(strConnect);
}
//导入前的回调函数
function showRequest(){
var excelFile = $("#importFile").val();
if(excelFile=='') {
$('.modal-pop').css('display', 'none');
alert("请选择需上传的文件!");
return false;
}
if(excelFile.indexOf('.xlsx')==-1){
$('.modal-pop').css('display', 'none');
alert("文件格式不正确,请选择正确的Excel文件(后缀名.xlsx)!");
return false;
}
var excelFileArr=excelFile.split("\\");
var fileName=excelFileArr[excelFileArr.length-1]
if(fileName!="shopInfoTemplate.xlsx"){
$('.modal-pop').css('display', 'none');
alert("请上传正确的Excel模板!");
return false;
}
}
注意:提交表单时,做了防止表单重复提交的处理(详见代码及注释),同时设置了服务器的响应的数据类型为”text/html“,这是为解决IE9以下版本做的前台处理,后台处理返回对应的数据类型即可。代码如下:
java代码:
/**
* @ClassName: MshopInfoImportAction
* @Description: (导入门店信息模板功能Action)
* @author: 阿Q
* @date 2019年8月12日
*/
@SuppressWarnings("serial")
@Action("importShopInfo")
//@ParentPackage("json-default")
@Namespace("/merchant/shop")
@Results({
//@Result(name="success", type = "json", params = {"root", "errorMsg"})
})
public class MshopInfoImportAction extends CommonAction{
//要与前台<input />标签中的name属性名保持一致
private File importFile;
@Autowired
private MshopInfoService shopInfoService;
private static final Log log = LogFactory.getLog(MshopInfoImportAction.class);
public List<String> errorMessages = new ArrayList<String>();
/**
* @throws IOException
* @throws FileNotFoundException
* @Title: importShopInfo
* @Description: (导入方法)
* @param 参数
* @return void 返回类型
* @throws
*/
public String importShopInfo(){
try {
errorMessages=this.readExcel(importFile);
} catch (Exception e) {
e.printStackTrace();
errorMessages.add("系统异常,请稍后重试");
log.info("导入中抛出异常了。。。。。");
}
ajax(errorMessages);
return "success";
}
/**
* @Title: readExcel
* @Description: TODO(读取excel模板内容)
* @param @return 参数
* @return List<Map<String,String>> 返回类型
* @throws
*/
public List<String> readExcel(File importFile) throws Exception{
//略.....
return errorMessages;
}
/**
* @Title: ajax
* @Description: (通过输出流,向ajax请求写结果)
* @param @param out
* @param @return 参数
* @return String 返回类型
* @throws
*/
public String ajax(List<String> list){
PrintWriter writer = null;
try {
HttpServletResponse response = ServletActionContext.getResponse();
response.setContentType("text/html;charset=utf-8");//application/json
writer = response.getWriter();
String jsonString = JSON.toJSONString(list);
writer.write(jsonString);
writer.flush();
} catch (Exception e) {
e.printStackTrace();
}finally{
if(writer!=null){
writer.close();
}
}
return null;
}
//部分方法及Getter和Setter方法略....
}
未解决IE兼容性问题,并未返回json格式数据给前台,前台设置的服务器响应的数据类型为”text/html“,后台也要设置响应类型为”text/html;charset=utf-8“。
参考文章:http://www.myexception.cn/ajax/1513711.html