透過Ajax上傳檔案(Javascript)

使用Javascript和Ajax實現上傳檔案到伺服器的功能

上傳檔案的tag使用input type=file,並且放在form裡面,程式碼如下:

<form id="uploadForm">
    <input name="file" id="file" type="file" accept=".pdf">
</form>

form給個id叫uploadForm,form裡面的input都要給name屬性值

name屬性值會對應到後端方法的參數名稱,所以必須要一致

另外還有一個accept屬性,可以限定上傳檔案的類型

這裡是限定pdf檔,若不加則可以選擇任何類型

但實際上還是可以上傳任何類型的檔案

所以若要強制限定pdf檔,就得用JS寫個方法判斷副檔名是否為.pdf

寫一個按鈕,點擊按鈕就會上傳檔案,建議不要寫在form裡面:

<button id="uploadFile">上傳附件</button>

 

再來是JS的部分:

$("#uploadFile").on("click", function () {
    var file = $("#file").val();
    if (file == null || file == "") {
        alert("請上傳附件!!!");
    } else {

        var formData = new FormData($("#uploadForm")[0]);

        $.ajax({
            url: '@Url.Action("UploadFile","Test")',
            contentType: false,
            async: false,
            type: "POST",
            cache: false,
            processData: false,
            data: formData,
            error: function (jqXHR, textStatus, errorThrown) {
                console.log("FAIL: " + errorThrown);
            },
            success: function (data, textStatus, jqXHR) {
                var _msg = jQuery.parseJSON(data);
                alert(_msg);
            }
        })
    }
})

先判斷有沒有上傳檔案,若有就建立一個FormData物件

該物件會包含指定的表單內容,而且建構式限定要放入form tag的元件

這也就是為什麼我們會將input放在form裡

再來因為jQuery是個物件集合,所以後面加上[0]

 

然後就使用ajax傳送到後段去,以下為參數設定:

url:傳送位置,這裡是連結到.NET MVC的Controller方法

contentType:要送到伺服器的資料類型,不寫的話預設為'application/x-www-form-urlencoded; charset=UTF-8',

最常用的是'application/json; charset=utf-8',用來傳送json格式的資料

async:設定是否同步

type:傳送檔案類型,通常使用post(安全性問題)

cache:設定是否使用快取,不使用則強迫每次都要送出請求,若使用快取的話,相同的請求第二次就不會送出,而直接取上一次送出的值

processData:是否處理資料,通常資料格式不是xml時會自動將送出的資料轉成字串,所以這裡設定false

data:要傳送的資料,這裡就放要傳送的FormData物件

送出之後我只設定成功或失敗會跳alert()顯示成功或失敗的原因

 

最後來看看後端,我使用C#給各位做參考:

public ActionResult UploadFile(System.Web.HttpPostedFileBase file)
{
    string result;
    try
    {
        var filePath = "C:/fakepath";
        var fileName = file.FileName;
        file.SaveAs(System.IO.Path.Combine(filePath, fileName));
        result = "success";
    }
    catch (Exception ex) 
    {
        result = "fail : " + ex.ToString();
    }

    return Json(JsonConvert.SerializeObject(result), JsonRequestBehavior.AllowGet);
}

參數名稱和form的name屬性相同都是file,而類別要使用System.Web.HttpPostedFileBase

先使用FileName屬性取得檔案名帶給filaName

再指定儲存檔案的資料夾路徑filePath(這裡我掛空值,使用時請放上自己的路徑)

最後用SaveAs方法儲存檔案,方法裡面的參數就放路徑

而我使用Path.Combine將檔案名和路徑合併成完整的路徑,這樣就成功存檔啦

 

處理完最後回傳結果字串,這裡我使用json來回傳

JsonConvert.SerializeObject將字串序列化成json格式的字串

後面要加上JsonRequestBehavior.AllowGet才能成功傳送

所以上傳成功後前端會用jQuery.parseJSON(data)將後端傳到前端的json格式的字串物件化成json物件