1. 程式人生 > >考慮瀏覽器兼容的文件上傳(IE8不支持FormData)

考慮瀏覽器兼容的文件上傳(IE8不支持FormData)

can utf pre next() ace 6.0 ogre tle 使用

方法一:使用FormData(因IE8不支持FormData, IE10才支持,因此此方法不兼容IE10以下的IE瀏覽器)
也可參考文章 http://www.jianshu.com/p/46e6e03a0d53

html:

<input type="file" class="form-control" id="inputfile" title="多個文件請打包後再上傳" style="display:inline-block;width:100%;_overflow:hidden;" />

js:

//新增行的保存及上傳文件
function uploadFile(data) {
    var fileObj = document.getElementById("inputfile").files; //
js 獲取文件對象 var FileController = "/action/add"; // 接收上傳文件的後臺地址 var form = new FormData(); //20160301 添加其他參數 form.append("param1",param1); form.append("param2",param2); if (fileObj.length != 0) { var i = fileObj.length; for (var j = 0; j < i; j++) { form.append(
"file" + j, fileObj[j]); // 文件對象 } } form.append("data", data); // XMLHttpRequest 對象 xmlHttpRequest = new XMLHttpRequest(); xmlHttpRequest.onreadystatechange = callback; xmlHttpRequest.open("post", FileController, true); /* event listeners */ // 進度條 // xmlHttpRequest.upload.addEventListener("progress", progressFunction, false);
// xmlHttpRequest.addEventListener("load", uploadComplete, false); // xmlHttpRequest.addEventListener("error", uploadFailed, false); // xmlHttpRequest.addEventListener("abort", uploadCanceled, false); /* end listeners */ xmlHttpRequest.send(form); } function callback() { // 接收響應數據 // 判斷對象狀態是否交互完成,如果為4則交互完成 if (xmlHttpRequest.readyState == 4) { // 判斷對象狀態是否交互成功,如果成功則為200 if (xmlHttpRequest.status == 200) { // 接收數據,得到服務器輸出的純文本數據 var response = xmlHttpRequest.responseText; //console.log(response); if(response == 1) { enabledButton(); alert("保存成功!"); } else { alert("保存失敗,請重新嘗試!"); } enableButton(); }else{//!=200 alert("保存失敗!"); enableButton(); } } }

方法二:使用form提交 兼容各種瀏覽器,form提交後會刷新頁面,且不太好獲取返回參數。如要返回原始頁面,需要用response.sendRedirect(原始頁面url)進行轉向。
html:

<form id="uploadFileForm" name="uploadFileForm" enctype="multipart/form-data" method="post">
            <input type="hidden" id="param1" name="param1" value="123"/>
            <input type="hidden" id="param2" name="param2" value="測試參數"/>
            <div id="uploadFileTableDiv" style="margin-left:10%;">
                <table border="1" width="80%">
                    <tr>
                       <td style="padding:10px;">
                          <span style="float:left;">上傳文件:&nbsp;&nbsp;</span>
                       </td> 
                       <td style="padding:10px;"> 
                           <input type="file" id="attach" name="attach" size="25" style="height:30px;" />
                       </td>
                    </tr>
                    <tr>
                       <td colspan="2" style="padding:10px;padding-left:50px;">
                            <button id="submit_btn" type="button" class="btn btn-default" onclick="javascript:submitFile();">
                                                                  上傳文件
                            </button>
                       </td>     
                    </tr>
                </table>
            </div>
        </form>   

js:

//20160612 文件上傳按鈕 form表單提交
function submitFile(){
    var attach = document.getElementById("attach").value;
    alert("attach: " + attach);

    if(attach == undefined || attach == ""){
        alert("請選擇文件");
        return;
    }


    uploadFileForm.action = "/tools/uploadFileAction";
    uploadFileForm.submit();

}

方法三:使用jquery.form.js支持的ajaxsubmit進行文件上傳
htm

<script th:src="@{/jquery/3.46.0/jquery.form.js}"></script>
<form id="uploadFileForm2" name="uploadFileForm2" enctype="multipart/form-data" method="post">
            <div id="uploadFileTableDiv2" style="margin-left:10%;">
                <table border="1" width="80%">
                    <tr>
                       <td style="padding:10px;">
                          <span style="float:left;">上傳文件:&nbsp;&nbsp;</span>
                       </td> 
                       <td style="padding:10px;"> 
                           <input type="file" id="attach2" name="attach2" size="25" style="height:30px;" />
                       </td>
                    </tr>
                    <tr>
                       <td colspan="2" style="padding:10px;padding-left:50px;">
                            <button id="submit_btn2" type="button" class="btn btn-default" onclick="javascript:ajaxSubmitFile();">
                                                                  上傳文件
                            </button>
                       </td>     
                    </tr>
                </table>
            </div>
        </form>   

js:

//在表單上追加input hidden元素 存放其他參數
function appendInputElementForForm(formId,inputName,inputValue){
      var myh = document.createElement("input");   
      myh.type = "hidden";   
      myh.value = inputValue;   
      myh.id = inputName;   
      myh.name = inputName; 
      document.getElementById(formId).appendChild(myh);   
      alert(document.getElementById(inputName).value);   
}

//20170207 文件上傳ajax Form表單提交
function ajaxSubmitFile(){
    var attach = document.getElementById("attach2").value;
    alert("ajaxSubmitFile attach2: " + attach);

    if(attach == undefined || attach == ""){
        alert("請選擇文件");
        return;
    }

    appendInputElementForForm( "uploadFileForm2", "param1", "123");
    appendInputElementForForm( "uploadFileForm2", "param2", "測試參數");

    $(‘#uploadFileForm2‘).ajaxSubmit({
            type:"post",
            url:"/tools/ajaxUploadFileAction",
            data:$(‘#uploadFileForm2‘).serialize(),
            dataType:"json",
            error:function(data){
                alert(data);
            },
            success:function(data){
                alert("ajaxSubmit上傳成功");
                alert("下載地址: " + data.data.attachment);
            }

    });     
}

最後附帶上後臺的java代碼:

//20160612 文件上傳
@RequestMapping(value = "ajaxUploadFileAction")
public ModelAndView ajaxUploadFile(HttpServletRequest request, HttpServletResponse response) throws Exception{      
    ResponseInfo responseInfo = new ResponseInfo(); 
    logger.info("ajaxUploadFile param1: " + request.getParameter("param1"));
    logger.info("ajaxUploadFile param2: " + request.getParameter("param2"));

    try {
        //將當前上下文初始化給CommonsMutipartResolver (多部分解析器)
        CommonsMultipartResolver multipartResolver=new CommonsMultipartResolver(                    request.getSession().getServletContext());

        // 判斷是否是多數據段提交格式
        if (multipartResolver.isMultipart(request)) {
              MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;

             logger.info("ajaxUploadFile param1: " + multiRequest.getParameter("param1"));
             logger.info("ajaxUploadFile param2: " + multiRequest.getParameter("param2"));

            Iterator<String> iter = multiRequest.getFileNames();
            logger.info("iter.hasNext(): "+iter.hasNext());
            Integer fileCount = 0;
            while (iter.hasNext()) {
                  MultipartFile multipartFile = multiRequest.getFile(iter.next());
                  String fileName = multipartFile.getOriginalFilename();
                  logger.info("upload demand filename: " + fileName );
                  //20170207 針對IE環境下filename是整個文件路徑的情況而做以下處理
                  Integer index = fileName.lastIndexOf("\\");
                  String newStr = "";
                  if(index>-1){
                        newStr = fileName.substring(index+1);

                  }else{
                        newStr = fileName;
                  }
                  if(!newStr.equals("")){
                        fileName = newStr;
                  }
                  logger.info("new filename: " + fileName );

                  if (multipartFile != null) {
                     HashMap<String,Object> result =  DispatchInterfaceUtil.uploadFileByInputStream (multipartFile.getInputStream(),multipartFile.getSize(),fileName);

                     Integer statusCode = (Integer)result.get("statusCode");                                                                       
                     logger.info("statusCode: " + statusCode);
                    if( statusCode.equals(0) ){                     
                      String attachment = (String)result.get("attachment");
                      responseInfo. setStatus(true);
                      responseInfo.put("attachment", attachment);
                   }else{
                      String errorMessage = (String)result.get("errorMessage");
                     logger.error( "errorMessage: "  + errorMessage);

                    responseInfo.setStatus(false); 
                    responseInfo.setMsg("文件上傳失敗");
                }                       
            }
            fileCount++;
         }//while
         logger.info("fileCount: " + fileCount);
       }
     }catch (Exception e) {
         // TODO: handle exception
         responseInfo.setStatus(false);
         responseInfo.setMsg("後臺出現異常");
         logger.warn("Error: ", e);
    }
    response.setContentType("text/html; charset=utf-8");
    response.getWriter().write( JSON.toJSONString(responseInfo));

    return null;
 }

註意:
(1)IE10可以支持application/json格式的Response了,也就是說低於IE10版本一下的IE瀏覽器都需要使用text/html格式的Response。 在Response頭中指定Content-Type為text/html,是可以解決問題的。這樣返回給客戶端的是一個JSON字符串(並非JSON對象),無需IE來解析。
(2)通過js動態添加的input file元素是無法通過form submit的方式(如上所述的後兩種方法)將文件內容提交給後臺進行文件上傳的,因為後臺服務器根本不知道有此元素. 若需要動態添加,可以先在html頁面中添加上不可見的input file元素(這樣後臺服務器就知道了該元素的存在), 需要添加時再通過js語句
document.getElementById(父元素ID).appendChild(inputFile元素對象)
將input file對象添加在適當位置

(3)在$.each代碼塊內不能使用break和continue,要實現break和continue的功能的話,要使用其它的方式:
break—-用return false;
continue –用return true;

考慮瀏覽器兼容的文件上傳(IE8不支持FormData)