1. 程式人生 > >檔案上傳中submit與ajax的問題與思考

檔案上傳中submit與ajax的問題與思考

檔案上傳在專案中經常需要,先上一段程式碼,用的easyUI

<form id="file_form" method="post" action="/upload"
        enctype="multipart/form-data">
        <div style="margin-bottom: 20px">
            <div>任務名稱:</div>
            <input id="task_name" name="task_name" class="easyui-textbox"
                style="width: 100%; height: 30px;"
> </div> <div style="margin-bottom: 20px"> <div>任務描述:</div> <input id="task_descrption" name="task_descrption" class="easyui-textbox" style="width: 100%; height: 30px;"> </div> <div style="margin-bottom: 20px"
> <div>類入口:</div> <input id="task_mainClass" name="task_mainClass" class="easyui-textbox" style="width: 100%; height: 30px;"> </div> <div style="margin-bottom: 20px"> <div>檔案:</div> <input class
="easyui-filebox" id="file" name="file" data-options="prompt:'請選擇檔案...'" style="width: 100%; height: 30px;"> </div> <div> <a id="upload" href="#" class="easyui-linkbutton" style="width: 100%; height: 30px;">上傳</a> </div> </form>

注意:form中一定不要忘記設定enctype=”multipart/form-data”
那麼接下來的問題來了,怎麼將檔案上傳到伺服器?通常有兩種思路,一是採用submit方法,另一種採用ajax(有人可能要拍磚了,ajax不是不能上傳檔案嗎?)

(1)submit

其實只需要使用

document.getElementById("file_form").submit();

或者

$("#file_form").submit();

註解1:如果採用表單名.submit()這種提交方式,可能會有一些問題,因為這種寫法不符合W3C標準的規定的,在IE下沒有報錯因為IE支援這種寫法,但是如果在FF下就會報錯,建議採用上述的document的方式。

註解2:怎麼知道檔案是否上傳成功了呢?很不幸的是submit沒有返回值!


submit Method 

Submits the form.

Syntax

FORM.submit()
Return Value

No return value.

Remarks

The submit method does not invoke the onsubmit event handler. 
Call the onsubmit event handler directly. 
When using Microsoft® Internet Explorer 5.5 and later, 
you can call the fireEvent method with a value of onsubmit in the sEvent parameter.

當然即使submit沒有返回值,我們還是有手段去知道檔案的上傳進度和上傳成功與否的狀態!

(2)ajax
jQuery的ajax()方法使得前端與後臺的互動變得更加的簡單與便捷。ajax不是不能用於上傳檔案!有人不僅要問網上有很多ajax用於檔案上傳,在這裡只能說那只是“表象”,他們基本原理都是用js建立一個內部窗體iframe,用建立的iframe去提交檔案,實現不重新整理當前頁面的委ajax效果。

ajax為什麼不能用於檔案上傳:ajax與後臺通訊都是通過傳遞字串,怎麼能傳遞檔案呢?其實出於安全考慮js是不允許訪問客戶端的檔案系統的(某些瀏覽器的外掛除外),所以我們無法拿到檔案控制元件裡的資料。

當然網上有很多偽ajax的控制元件,如jquery.form.js /filesaver.js,如簡單介紹jquery.form.js:

前端程式碼

$("#upload").click(function(){
    $('#file_form').ajaxSubmit({
          dataType : 'json',
          success : function(data) {                                
        }
   });
});

注意在form中已經填寫了action的地址!
後端程式碼實現

@RequestMapping(value = "/upload", method = { RequestMethod.POST,
            RequestMethod.GET })
    @ResponseBody
    public void upload(
            final HttpServletRequest request, HttpServletResponse response,
            @RequestParam(value = "file") MultipartFile... files)
            throws IOException, Exception {
        for (MultipartFile f : files) {
            if (f.getSize() > 0) {
                File targetFile = new File("D:/" + f.getOriginalFilename());
                String filename = targetFile.getName();
                f.transferTo(targetFile);// 寫入目標檔案          
            }
        }

    }