需求背景:需求需要實現上傳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