install modules
npm install formidable --save-dev
npm install node-static --save-dev
catalog
upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content='width=device-width,initail-scale=1'/>
<meta content="telephone=no" name="format-detection"/>
<meta content="address=no" name="format-detection"/>
<title>upload</title>
<link rel="stylesheet" href="./upload.css"/>
</head>
<body>
<div class="row"> <!-- 第一行显示上传按钮 -->
<label> usericon:</label>
<input class="uploadinput" type='file'/>
<span class="uploadicon">上传图片</span> <!-- 美化上传按钮 -->
</div>
<div class="row"> <!-- 第二行显示上传进度 -->
<label>progress:</label>
<span class="state"></span>
</div>
<div class="row"> <!-- 第三行显示预览图片 -->
<label>preview:</label>
<img class="preview" src=''/>
</div>
<script type="text/javascript" src="./jquery.min.js"></script>
<script type="text/javascript" src="./upload.js"></script>
</body>
</html>
upload.css
.row{
display: block;
width:100%;
line-height:40px;
}
.row label{
font-size:15px;
color:rgba(0,0,0,.5);
display: inline-block;
margin-right:20px;
width:54px;
}
.row progress{
display: inline-block;
}
.row input[type='file']{
display: none;
}
.row .uploadicon{
display: inline-block;
width:80px;
line-height:27px;
text-align: center;
height:27px;
color:white;
vertical-align: middle;
background-color:burlywood ;
font-size:13px;
}
.row .preview{
display: block;
width:100%;
height:40vh;
box-shadow: 2px 2px 5px rgba(0,0,0,.2);
border:none;
}
.state{
color:red;
font-size:15px;
}
upload.js
var image = document.querySelector(".preview");//图片预览的容器
var progress = document.querySelector(".state");//显示上传状态的容器
$('.uploadicon').click(function(){//利用美化上传图片按钮的单击触发input[type='file]的单击事件
$('.uploadinput').click();
});
document.querySelector(".uploadinput").onchange = function(){//监听change事件获得上传文件
var files = this.files;
if(files.length === 0){
return;
}
var file = this.files[0];
uploadFile(file);//上传到服务器
readAsDataURL(file, image);//实现图片预览功能
}
function readAsDataURL(file, image){
var reader = new FileReader();
// 将文件以Data URL形式进行读入页面
reader.readAsDataURL(file);
reader.onload = function(e){
image.src = this.result;
}
}
function uploadFile(file){
var formData = new FormData();//h5提供的存储图片数据的接口
formData.append(file.name, file);
$.ajax({
url: 'upload',//默认当前页地址
type: 'POST',
data: formData,//上传数据
// 这两项必填,作为文件上传的时候
contentType: false,
processData: false,
beforeSend: function(xhr) {
xhr.progress = function(e) {
console.log(e);
var percent = Math.floor(e.loaded / e.total *100);
progress.innerHTML = percent +"%";
};
},
success: function(resp) {
progress.innerHTML = "上传成功";
},
error: function() {
progress.innerHTML = "上传失败";
}
});
}
server.js
var http = require("http"); // 用于web服务器
var path = require('path'); // 用于路径操作
var fs = require('fs'); // 用于文件操作
var formidable = require("formidable"); // 用于解析HTTP协议里的Multipart格式,提取文件内容
var static = require('node-static'); // 用于提供静态资源
var staticServer = new static.Server('./public'); // 将public目录作为静态资源目录
function handleStaticRequest(req, res) { // 处理静态资源请求
req.addListener('end', function () { // 监听HTTP请求结束事件
staticServer.serve(req, res); // 提供静态资源服务
}).resume();
}
function handlefileUploadRequest(req, res) { // 处理文件上传请求
if (req.method === "POST") { // 文件上传请求必须是POST方法
var form = new formidable.IncomingForm(); // 构建form实例
form.on('error', function (error) { // 监听form上传出错事件
res.writeHead(500); // 设置响应头
res.write('上传失败,' + error); // 设置上传失败状态码和信息
res.end(); // 结束响应
}).parse(req, function(error, fields, files){ // 解析from上传数据
for(var key in files) { // 遍历上传文件
var file = files[key]; // 上传文件
var ws = fs.createWriteStream(path.resolve(__dirname, 'public/images', file.name)); // 构建写入流
fs.createReadStream(file.path).pipe(ws); // 写入上传文件至服务器文件夹
}
res.writeHead(200); // 设置响应头
res.end(); // 结束响应
});
}
}
var app = http.createServer(function(req, res) { // 创建WEB服务器
handleStaticRequest(req, res); // 处理静态资源请求
handlefileUploadRequest(req, res); // 处理文件上传请求
});
app.listen(8080, function(){ // 监听8080端口
console.log("listen at port http://localhost:8080");
});