小明問說他要製作在網頁中上傳檔案, 但不知道要怎麼做?
提供使用者將檔案上傳到伺服器的能力時, 請務必小心. 因為攻擊者可能會嘗試
降低成功攻擊的可能性的安全性方法如下
當涉及到上傳較大的檔案時, 一般人總是認為直接修改Web 設定
maxRequestLength 和 maxAllowedContentLength 設定
這絕對不是正確的做法, 因為你總不可能無限制地加大Request 上傳大小,
加大上傳大小更容易受到阻斷服務的攻擊.
而且一次性上傳大檔案會遇到很多挑戰, 例如UI 回應能力, 上傳進度, 客戶端必須再次上載等等.
在這種情況下, 最好分塊上傳大檔案, 它具有很多優點, 例如
在這裡我將展示如何以小塊形式上傳檔案
首先在網頁中輸入以下內容
<input type="file" accept=".pdf,.png" onChange="fileUpload">
接著準備Javascript 程式碼
<script>
function fileUpload(sender) {
var fileList = sender.currentTarget.files;
var file = fileList[0];
chunky(file, 0);
}
function chunky(file, chunkIndex) {
let chunkSize = 1024 * 4;
let totalSize = file.size;
let totalChunkSize = Math.floor((totalSize + chunkSize - 1) / chunkSize);
if( chunkIndex >= totalChunkSize ) {
return;
}
let start = chunkIndex * chunkSize;
let blob = file.slice(start, start + chunkSize);
var dataForm = new DataForm();
dataForm.append("fileUpload", blob, file.name);
dataForm.append("chunkIndex", chunkIndex);
dataForm.append("totalSize", totalSize);
$.ajax({
url: "/Home/UploadFileChunk",
type: "POST",
processData: false,
contentType: false
data: dataForm
}).done(function(r){
chunky(file, chunkIndex+1);
});
}
</script>
在客戶端將每個檔案切成小塊,每一塊大小在 "chunkSize" 中指定, 您可以更改此大小.
Javascript 上傳每個塊, 然後等待其完成, 然後再開始上傳下一個塊.
以下是伺服器端的實作程式碼
public class UploadRequest {
public HttpPostedFileBase File { get; set }
public int ChunkIndex { get; set; }
public int TotalSize { get; set; }
}
public ActionResult UploadFileChunk(UploadRequest req) {
var inputStream = req.File.InputStream;
using(var fs=new FileStream("D:/tmp/customer.png", FileMode.Append, FileAccess.Write))
{
var buffer = new byte[1024];
var readSize = inputStream.Read(buffer, 0, 1024);
while (readSize > 0)
{
fs.Write(buffer, 0, readSize);
readSize = inputStream.Read(buffer, 0, 1024);
}
fs.Flush();
fs.Close();
}
return Json("OK");
}
這只是個示範示意程式, 不是正式完整的程式碼.
在伺服器端, 我們都接收到前端傳送過來是一個單獨的檔案塊, 將其保存到臨時資料夾中,
每次收到檔案塊, 需要將它們合併回原始檔案中.
所以我們需要輸入三個參數(檔案區塊內容File, 塊索引ChunkIndex, 原始檔案的總共大小TotalSize)
你必須檢查這三個參數內容是否合法.
最後我們需要注意以下幾點
就是這樣-祝您上傳愉快!