要實現前端檔案無重新整理上傳,主要有以下幾種方法:
1. 使用 FormData 和 XMLHttpRequest/Fetch API:
這是最常用的方法,相容性好,可以自定義上傳進度和錯誤處理。
- 建立 FormData 物件: FormData 物件可以模擬表單提交,用於儲存上傳的檔案和其他資料。
- 使用 XMLHttpRequest 或 Fetch API 傳送請求: 將 FormData 物件作為請求體傳送到伺服器。
- 監聽上傳進度: 可以使用 XMLHttpRequest 的
upload.onprogress
事件或 Fetch API 的ReadableStream
來監聽上傳進度。 - 處理伺服器響應: 在
onload
事件中處理伺服器返回的資料。
const fileInput = document.getElementById('fileInput');
const uploadForm = document.getElementById('uploadForm');
uploadForm.addEventListener('submit', (event) => {
event.preventDefault();
const file = fileInput.files[0];
const formData = new FormData();
formData.append('file', file);
const xhr = new XMLHttpRequest();
xhr.open('POST', '/upload');
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
console.log(`Uploaded ${percentComplete}%`);
}
};
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
console.log('Upload successful:', xhr.response);
} else {
console.error('Upload failed:', xhr.status, xhr.statusText);
}
};
xhr.onerror = () => {
console.error('Upload error');
};
xhr.send(formData);
});
// 使用Fetch API的示例:
async function uploadFile(file) {
const formData = new FormData();
formData.append('file', file);
try {
const response = await fetch('/upload', {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
const data = await response.json();
console.log('Upload successful:', data);
} catch (error) {
console.error('Upload failed:', error);
}
}
2. 使用 Axios 庫:
Axios 是一個流行的 JavaScript HTTP 客戶端庫,可以簡化 AJAX 請求的編寫。
import axios from 'axios';
const file = fileInput.files[0];
const formData = new FormData();
formData.append('file', file);
axios.post('/upload', formData, {
onUploadProgress: (progressEvent) => {
const percentComplete = Math.round((progressEvent.loaded * 100) / progressEvent.total);
console.log(`Uploaded ${percentComplete}%`);
},
})
.then((response) => {
console.log('Upload successful:', response.data);
})
.catch((error) => {
console.error('Upload failed:', error);
});
3. 使用 HTML5 的 File API 配合 FileReader API (適合小檔案,base64編碼):
對於小檔案,可以直接使用 FileReader API 將檔案讀取為 Base64 字串,然後透過 AJAX 傳送到伺服器。這種方法的優點是簡單,缺點是對於大檔案效率較低,並且會增加資料傳輸量。
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = (e) => {
const base64String = e.target.result;
fetch('/upload', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ file: base64String }),
})
.then(response => response.json())
.then(data => console.log('Upload successful:', data))
.catch(error => console.error('Upload failed:', error));
};
reader.readAsDataURL(file);
});
選擇哪種方法取決於專案需求:
- 對於大檔案上傳,建議使用 FormData 和 XMLHttpRequest/Fetch API 或 Axios,可以監聽上傳進度。
- 對於小檔案