使用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物件