# JavaScript怎么讀取上傳文件內容/類型/字節數
## 目錄
1. [文件上傳基礎](#文件上傳基礎)
2. [獲取文件對象](#獲取文件對象)
3. [讀取文件元信息](#讀取文件元信息)
- [文件類型檢測](#文件類型檢測)
- [文件大小限制](#文件大小限制)
4. [讀取文件內容](#讀取文件內容)
- [文本文件讀取](#文本文件讀取)
- [二進制文件處理](#二進制文件處理)
5. [高級文件操作](#高級文件操作)
- [大文件分片讀取](#大文件分片讀取)
- [圖片預覽生成](#圖片預覽生成)
6. [安全注意事項](#安全注意事項)
7. [完整代碼示例](#完整代碼示例)
8. [瀏覽器兼容性](#瀏覽器兼容性)
## 文件上傳基礎
在Web開發中,文件上傳是常見需求。HTML5提供了`<input type="file">`元素實現文件選擇功能:
```html
<input type="file" id="fileInput">
當用戶選擇文件后,可以通過JavaScript訪問File API來獲取文件信息?,F代瀏覽器支持以下核心對象:
通過DOM獲取文件對象的基本方法:
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', (event) => {
const files = event.target.files; // FileList對象
if (files.length > 0) {
const firstFile = files[0];
console.log('獲取到文件:', firstFile);
}
});
每個File對象包含以下重要屬性:
屬性名 | 類型 | 描述 |
---|---|---|
name | String | 文件名(不含路徑) |
size | Number | 文件大?。ㄗ止潱?/td> |
type | String | MIME類型 |
lastModified | Number | 最后修改時間戳 |
lastModifiedDate | Date | 最后修改日期對象 |
實際開發中需要注意:
// 實際文件類型檢測函數
function checkFileType(file, expectedTypes) {
const typeMap = {
'image/png': [0x89, 0x50, 0x4E, 0x47],
'image/jpeg': [0xFF, 0xD8, 0xFF]
};
return new Promise((resolve) => {
const reader = new FileReader();
reader.onload = (e) => {
const arr = new Uint8Array(e.target.result.slice(0,4));
const header = Array.from(arr).map(b => b.toString(16));
const isExpected = expectedTypes.some(type => {
const signature = typeMap[type];
return signature.every((byte, i) => byte === arr[i]);
});
resolve(isExpected);
};
reader.readAsArrayBuffer(file.slice(0,4));
});
}
前端驗證文件大小示例:
const MAX_SIZE = 10 * 1024 * 1024; // 10MB
function validateFileSize(file) {
if (file.size > MAX_SIZE) {
alert(`文件大小不能超過${MAX_SIZE/1024/1024}MB`);
return false;
}
return true;
}
使用FileReader讀取文本內容:
function readTextFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsText(file);
});
}
// 使用示例
readTextFile(someFile)
.then(content => console.log(content))
.catch(err => console.error(err));
處理二進制數據的幾種方式:
// 讀取二進制數據并計算SHA-256哈希
async function calculateFileHash(file) {
const buffer = await file.arrayBuffer();
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
處理大文件時推薦分片讀?。?/p>
const CHUNK_SIZE = 1 * 1024 * 1024; // 1MB
async function* chunkFile(file) {
let offset = 0;
while (offset < file.size) {
const chunk = file.slice(offset, offset + CHUNK_SIZE);
const buffer = await chunk.arrayBuffer();
yield buffer;
offset += CHUNK_SIZE;
}
}
// 使用示例
for await (const chunk of chunkFile(largeFile)) {
// 處理每個分片
}
生成圖片預覽的兩種方式:
URL.createObjectURL()
function createImagePreview(file) {
const img = document.createElement('img');
img.src = URL.createObjectURL(file);
img.onload = () => URL.revokeObjectURL(img.src);
return img;
}
Canvas壓縮預覽
async function createCompressedPreview(file, maxWidth = 300) {
const img = await createImageBitmap(file);
const canvas = document.createElement('canvas');
const ratio = maxWidth / img.width;
canvas.width = maxWidth;
canvas.height = img.height * ratio;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
return canvas.toDataURL('image/jpeg', 0.8);
}
<!DOCTYPE html>
<html>
<head>
<title>文件上傳示例</title>
<style>
#preview { max-width: 300px; max-height: 300px; }
.progress { width: 100%; background: #f0f0f0; }
.progress-bar { height: 20px; background: #4CAF50; width: 0%; }
</style>
</head>
<body>
<input type="file" id="fileInput" multiple>
<div id="fileInfo"></div>
<img id="preview">
<div class="progress">
<div class="progress-bar"></div>
</div>
<script>
const fileInput = document.getElementById('fileInput');
const fileInfo = document.getElementById('fileInfo');
const preview = document.getElementById('preview');
const progressBar = document.querySelector('.progress-bar');
fileInput.addEventListener('change', async (event) => {
const files = event.target.files;
if (files.length === 0) return;
const file = files[0];
// 顯示文件信息
fileInfo.innerHTML = `
<p>文件名: ${file.name}</p>
<p>文件類型: ${file.type || '未知'}</p>
<p>文件大小: ${(file.size / 1024).toFixed(2)} KB</p>
<p>最后修改: ${new Date(file.lastModified).toLocaleString()}</p>
`;
// 圖片預覽
if (file.type.startsWith('image/')) {
preview.src = URL.createObjectURL(file);
preview.onload = () => URL.revokeObjectURL(preview.src);
}
// 分片讀取示例
if (file.size > 5 * 1024 * 1024) {
let uploaded = 0;
for await (const chunk of chunkFile(file)) {
uploaded += chunk.byteLength;
const percent = (uploaded / file.size * 100).toFixed(1);
progressBar.style.width = `${percent}%`;
progressBar.textContent = `${percent}%`;
// 這里可以發送分片到服務器
await new Promise(r => setTimeout(r, 100)); // 模擬上傳延遲
}
}
});
async function* chunkFile(file, chunkSize = 1 * 1024 * 1024) {
let offset = 0;
while (offset < file.size) {
const chunk = file.slice(offset, offset + chunkSize);
yield await chunk.arrayBuffer();
offset += chunkSize;
}
}
</script>
</body>
</html>
特性 | Chrome | Firefox | Safari | Edge | IE |
---|---|---|---|---|---|
File API | 7+ | 3.6+ | 6+ | 10+ | 10+ |
FileReader | 7+ | 3.6+ | 6+ | 10+ | 10+ |
Blob | 20+ | 13+ | 6+ | 12+ | 10+ |
File.slice() | 21+ | 13+ | 6.1+ | 12+ | 10+ |
File.arrayBuffer() | 76+ | 69+ | 14+ | 79+ | ? |
對于舊版瀏覽器,可以考慮使用第三方庫如: - Resumable.js - Flow.js - FileSaver.js
”`
這篇文章詳細介紹了JavaScript處理文件上傳的各個方面,從基礎操作到高級技巧,包含了約2900字的內容。文章采用Markdown格式編寫,包含代碼示例、表格和結構化目錄,適合作為技術文檔或博客文章發布。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。