Node.js是一个基于Chrome V8引擎的JavaScript运行环境,可以在服务器端轻松构建高性能、可扩展的网络应用。在Node.js的绝大部分网络应用中,使用http模块进行网络通信是必不可少的一步。本篇文章主要介绍如何使用http模块处理文件上传。
1. 准备工作
在使用Node.js进行文件上传前,需要先安装相关依赖包。目前最流行的文件上传中间件是[formidable](https://github.com/node-formidable/formidable),可以通过npm进行安装:
npm install formidable
2. 前端实现
前端使用<input type="file">
标签来实现文件选择,并在表单提交时将该标签的值赋给一个FormData对象,并通过ajax将FormData提交至服务器端。
2.1 FormData对象
FormData是一个表单数据构造器,可以用来模拟表单提交。它使用键值对的方式存储数据,支持二进制数据上传,并且可以避免手动拼接请求报文的繁琐过程。
上传表单里的文件时,我们可以使用FormData对象。以下是一个使用FormData对象上传图片的例子:
var formData = new FormData();
formData.append('file', document.querySelector('input[type="file"]').files[0]);
// Ajax
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload', true);
xhr.onreadystatechange = function(res) {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
};
xhr.send(formData);
这个例子中,我们构造了一个FormData对象,将input标签里选择的图片对象添加到formData里,并使用ajax将formData提交到服务器端。
2.2 Ajax实现
ajax实现方法有很多,这里我们以jQuery为例:
$('form').submit(function(e) {
e.preventDefault();
var formData = new FormData($(this)[0]);
$.ajax({
url: '/upload',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(res) {
console.log(res);
}
});
});
在这个例子中,我们使用了jquery的ajax方法,在表单提交时,首先使用preventDefault阻止表单的默认提交事件,在提交表单数据时,我们指定了url、type、data等参数,并且设置processData为false、contentType为false,表示禁止jQuery处理表单数据并使用formData的格式进行提交。
3. 后端实现
在服务器端,我们需要使用http
模块来搭建一个web服务器,并在其中处理ajax上传的文件。
3.1 创建服务器
我们可以使用http.createServer
方法创建一个服务器:
var http = require('http');
var server = http.createServer(function(req, res) {
// 处理请求
});
server.listen(3000, function() {
console.log('Server is listening at port 3000');
});
这个例子中,我们使用http.createServer方法创建了一个服务器,并对该服务器绑定了3000
端口。服务器启动后,可以通过http://localhost:3000
访问该服务器。
3.2 解析请求
在服务器接收到请求后,我们需要解析请求,获取前端传来的表单数据。这里我们使用formidable依赖包来解析表单数据:
var formidable = require('formidable');
var path = require('path');
var server = http.createServer(function(req, res) {
// 解析上传的文件
var form = new formidable.IncomingForm();
form.uploadDir = path.join(__dirname, 'uploads');
form.keepExtensions = true;
form.parse(req, function(err, fields, files) {
if (err) {
res.statusCode = 500;
res.end('Upload Failed');
return;
}
res.end('Upload Success');
});
});
这个例子中,我们首先引入了formidable
和path
依赖包,并使用new formidable.IncomingForm()
来实例化一个formidable对象。我们还设置了该对象的uploadDir
和keepExtensions
属性用于指定上传的文件所在目录和是否保留上传文件的扩展名。
最后我们使用form.parse(req, function(err, fields, files){})
来解析表单数据。在表单数据解析后,我们可以使用fields
对象获取表单中的非文件字段,files
对象获取表单中的文件字段。
3.3 文件上传
最后,我们需要将表单中上传的文件保存到服务器端,这里我们使用fs
模块的fs.rename()
方法将文件保存至服务器本地:
var fs = require('fs');
var formidable = require('formidable');
var path = require('path');
var server = http.createServer(function(req, res) {
// 解析上传的文件
var form = new formidable.IncomingForm();
form.uploadDir = path.join(__dirname, 'uploads');
form.keepExtensions = true;
form.parse(req, function(err, fields, files) {
if (err) {
res.statusCode = 500;
res.end('Upload Failed');
return;
}
// 保存上传文件
var uploadedFile = files.file;
var filePath = path.join(form.uploadDir, uploadedFile.name);
fs.rename(uploadedFile.path, filePath, function(err) {
if (err) {
res.statusCode = 500;
res.end('Upload Failed');
return;
}
res.end('Upload Success');
});
});
});
在这个例子中,我们首先引入了fs
模块,并在form.parse回调函数中使用fs.rename()
方法将上传的文件保存到目标目录。
4. 总结
这篇文章主要介绍了使用http
模块和formidable
依赖包,实现了Node.js服务器与前端进行文件上传和解析。在实际生产中,我们还需要注意上传的文件大小、文件类型、文件名等信息的校验,并对上传的文件进行签名和加密等操作,保证文件上传的安全可靠。