您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# JavaScript怎么读取上传文件内容/类型/字节数
## 目录
1. [文件上传基础](#文件上传基础)
2. [获取文件对象](#获取文件对象)
3. [读取文件元信息](#读取文件元信息)
- [文件类型检测](#文件类型检测)
- [文件大小限制](#文件大小限制)
4. [读取文件内容](#读取文件内容)
- [文本文件读取](#文本文件读取)
- [二进制文件处理](#二进制文件处理)
5. [高级文件操作](#高级文件操作)
- [大文件分片读取](#大文件分片读取)
- [图片预览生成](#图片预览生成)
6. [安全注意事项](#安全注意事项)
7. [完整代码示例](#完整代码示例)
8. [浏览器兼容性](#浏览器兼容性)
## 文件上传基础
在Web开发中,文件上传是常见需求。HTML5提供了`<input type="file">`元素实现文件选择功能:
```html
<input type="file" id="fileInput">
当用户选择文件后,可以通过JavaScript访问File API来获取文件信息。现代浏览器支持以下核心对象:
通过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 | 文件大小(字节) |
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('');
}
处理大文件时推荐分片读取:
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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。