HTML5 File API 文件操作教程
HTML5 File API 允许网页中的 JavaScript 访问和处理本地文件系统中的文件。通过这一 API,开发者可以在客户端对文件进行压缩、编码、加密等操作,或者实现分块上传功能。本教程将详细介绍 File API 的核心概念、使用方法以及安全限制。
核心对象
HTML5 File API 包含以下核心对象:
-
FileList:表示本地文件系统中的文件列表
-
File:代表单个文件对象
-
Blob(二进制大对象):用于存储文件的二进制数据
-
FileReader:用于读取文件内容
文件选择方法
通过 input 元素选择文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>代码号 - 文件选择示例</title>
</head>
<body>
<h2>选择学习资料</h2>
<input type="file" id="fileInput" onchange="handleFileSelection(event)">
<div id="fileInfo"></div>
<script>
function handleFileSelection(event) {
const fileList = event.target.files;
const infoDiv = document.getElementById('fileInfo');
if (fileList.length > 0) {
infoDiv.innerHTML = `<p>已选择文件: ${fileList[0].name}</p>
<p>文件大小: ${fileList[0].size} 字节</p>
<p>文件类型: ${fileList[0].type || '未知'}</p>`;
}
}
</script>
</body>
</html>
选择多个文件
<input type="file" id="multiFileInput" multiple onchange="handleMultipleFiles(event)">
<script>
function handleMultipleFiles(event) {
const fileList = event.target.files;
console.log(`选择了 ${fileList.length} 个文件`);
for (let i = 0; i < fileList.length; i++) {
console.log(`文件 ${i+1}: ${fileList[i].name}`);
}
}
</script>
拖拽选择文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>代码号 - 拖拽文件示例</title>
<style>
#dropZone {
width: 300px;
height: 200px;
border: 2px dashed #ccc;
border-radius: 8px;
text-align: center;
padding: 20px;
margin: 20px auto;
background-color: #f9f9f9;
}
#dropZone.dragover {
background-color: #e3f2fd;
border-color: #2196f3;
}
</style>
</head>
<body>
<div id="dropZone">
<p>将文件拖拽到此处</p>
<p>或点击下方按钮选择文件</p>
<input type="file" id="fileInput" multiple>
</div>
<div id="fileList"></div>
<script>
const dropZone = document.getElementById('dropZone');
const fileInput = document.getElementById('fileInput');
const fileListDiv = document.getElementById('fileList');
// 拖拽事件处理
dropZone.addEventListener('dragover', function(e) {
e.preventDefault();
e.stopPropagation();
dropZone.classList.add('dragover');
});
dropZone.addEventListener('dragleave', function(e) {
e.preventDefault();
e.stopPropagation();
dropZone.classList.remove('dragover');
});
dropZone.addEventListener('drop', function(e) {
e.preventDefault();
e.stopPropagation();
dropZone.classList.remove('dragover');
const files = e.dataTransfer.files;
handleFiles(files);
});
// 点击选择文件
dropZone.addEventListener('click', function() {
fileInput.click();
});
fileInput.addEventListener('change', function(e) {
handleFiles(e.target.files);
});
function handleFiles(files) {
fileListDiv.innerHTML = '';
const list = document.createElement('ul');
for (let i = 0; i < files.length; i++) {
const listItem = document.createElement('li');
listItem.textContent = `${files[i].name} (${formatFileSize(files[i].size)})`;
list.appendChild(listItem);
}
fileListDiv.appendChild(list);
}
function formatFileSize(bytes) {
if (bytes < 1024) return bytes + ' B';
else if (bytes < 1048576) return (bytes / 1024).toFixed(2) + ' KB';
else return (bytes / 1048576).toFixed(2) + ' MB';
}
</script>
</body>
</html>
文件读取方法
文本文件读取
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>代码号 - 文本文件读取示例</title>
</head>
<body>
<input type="file" accept=".txt,.csv,.html,.js,.css" onchange="readTextFile(this.files)">
<div id="textContent" style="margin-top: 20px; padding: 10px; border: 1px solid #ddd;"></div>
<script>
function readTextFile(files) {
if (files.length === 0) return;
const reader = new FileReader();
reader.onload = function(e) {
const contentDiv = document.getElementById('textContent');
contentDiv.textContent = e.target.result;
};
reader.onerror = function(e) {
console.error('文件读取错误:', e.target.error);
};
reader.readAsText(files[0]);
}
</script>
</body>
</html>
图片文件预览
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>代码号 - 图片预览示例</title>
<style>
.image-preview {
max-width: 300px;
max-height: 300px;
margin-top: 15px;
border: 1px solid #ddd;
padding: 5px;
}
</style>
</head>
<body>
<h3>图片预览功能</h3>
<input type="file" accept="image/*" onchange="previewImage(this.files)">
<div>
<img id="preview" class="image-preview" src="https://www.ebingou.cn/biancheng/images/1.jpg" alt="图片预览">
</div>
<script>
function previewImage(files) {
if (files.length === 0) return;
const reader = new FileReader();
const preview = document.getElementById('preview');
reader.onload = function(e) {
preview.src = e.target.result;
};
reader.readAsDataURL(files[0]);
}
</script>
</body>
</html>
二进制数据读取
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>代码号 - 二进制文件处理</title>
</head>
<body>
<input type="file" onchange="processBinaryFile(this.files)">
<div id="binaryInfo"></div>
<script>
function processBinaryFile(files) {
if (files.length === 0) return;
const reader = new FileReader();
const infoDiv = document.getElementById('binaryInfo');
reader.onload = function(e) {
const arrayBuffer = e.target.result;
const dataView = new DataView(arrayBuffer);
let info = `<h4>文件分析结果</h4>`;
info += `<p>文件大小: ${arrayBuffer.byteLength} 字节</p>`;
// 读取前几个字节进行分析
if (arrayBuffer.byteLength > 0) {
info += `<p>起始字节: `;
for (let i = 0; i < Math.min(10, arrayBuffer.byteLength); i++) {
info += ` ${dataView.getUint8(i).toString(16).padStart(2, '0')}`;
}
info += `</p>`;
}
infoDiv.innerHTML = info;
};
reader.readAsArrayBuffer(files[0]);
}
</script>
</body>
</html>
文件上传示例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>代码号 - 文件上传示例</title>
<style>
.progress-bar {
width: 300px;
height: 20px;
background-color: #f0f0f0;
border-radius: 10px;
margin: 10px 0;
overflow: hidden;
}
.progress {
height: 100%;
background-color: #4caf50;
width: 0%;
transition: width 0.3s;
}
</style>
</head>
<body>
<h2>编程学习资料上传</h2>
<input type="file" id="uploadFile">
<button onclick="uploadFile()">上传文件</button>
<div class="progress-bar">
<div class="progress" id="progressBar"></div>
</div>
<div id="uploadStatus"></div>
<script>
function uploadFile() {
const fileInput = document.getElementById('uploadFile');
const progressBar = document.getElementById('progressBar');
const statusDiv = document.getElementById('uploadStatus');
if (fileInput.files.length === 0) {
statusDiv.textContent = '请先选择文件';
return;
}
const file = fileInput.files[0];
const formData = new FormData();
formData.append('file', file);
formData.append('uploadDate', new Date().toLocaleDateString());
fetch('https://www.ebingou.cn/upload', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('上传失败');
}
return response.json();
})
.then(data => {
statusDiv.textContent = '上传成功';
statusDiv.style.color = 'green';
})
.catch(error => {
statusDiv.textContent = '上传失败: ' + error.message;
statusDiv.style.color = 'red';
});
}
</script>
</body>
</html>
进度监控示例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>代码号 - 文件读取进度</title>
<style>
.progress-container {
margin: 20px 0;
}
.progress-text {
margin-top: 5px;
font-size: 14px;
color: #666;
}
</style>
</head>
<body>
<input type="file" onchange="readFileWithProgress(this.files)">
<div class="progress-container">
<progress id="fileProgress" value="0" max="100"></progress>
<div class="progress-text" id="progressText">0%</div>
</div>
<script>
function readFileWithProgress(files) {
if (files.length === 0) return;
const reader = new FileReader();
const progressBar = document.getElementById('fileProgress');
const progressText = document.getElementById('progressText');
reader.onprogress = function(e) {
if (e.lengthComputable) {
const percentLoaded = Math.round((e.loaded / e.total) * 100);
progressBar.value = percentLoaded;
progressText.textContent = `${percentLoaded}% (${e.loaded}/${e.total} 字节)`;
}
};
reader.onloadend = function(e) {
if (e.loaded === e.total) {
progressText.textContent = '读取完成';
}
};
reader.readAsText(files[0]);
}
</script>
</body>
</html>
本节课程知识要点
-
安全限制:File API 只能访问用户明确选择的文件,无法随意访问整个文件系统
-
核心对象:FileList、File、Blob 和 FileReader 是 File API 的核心组件
-
多种读取方式:支持文本、Data URL、ArrayBuffer 等多种格式的文件读取
-
进度监控:可以实时监控文件读取进度,提升用户体验
-
应用场景:适用于文件预览、客户端处理、分块上传等场景
实际应用案例
代码文件语法高亮预览
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>代码号 - 代码文件预览</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
</head>
<body>
<h3>代码文件预览器</h3>
<input type="file" accept=".js,.html,.css,.py,.java" onchange="previewCodeFile(this.files)">
<pre><code id="codeBlock" class="language-javascript">// 选择代码文件后这里将显示内容</code></pre>
<script>
function previewCodeFile(files) {
if (files.length === 0) return;
const reader = new FileReader();
reader.onload = function(e) {
const codeBlock = document.getElementById('codeBlock');
codeBlock.textContent = e.target.result;
// 根据文件扩展名确定语言类型
const fileName = files[0].name;
const extension = fileName.split('.').pop();
codeBlock.className = `language-${extension}`;
// 高亮显示代码
hljs.highlightElement(codeBlock);
};
reader.readAsText(files[0]);
}
</script>
</body>
</html>
浏览器兼容性说明
目前主流现代浏览器均支持 HTML5 File API,包括 Chrome、Firefox、Safari、Edge 等。在实际开发中建议进行特性检测:
if (window.File && window.FileReader && window.FileList && window.Blob) {
// 浏览器支持 File API
} else {
alert('您的浏览器不支持 HTML5 File API');
}
通过本教程的学习,您应该已经掌握了 HTML5 File API 的基本用法和实际应用。这些技术可以广泛应用于文件处理、数据分析和前端开发等领域。