本节介绍做个例子,实现上传图片,并且显示图片,中间修改了原作者demo中的bug。
之前教程中的例子都可以脱离nodejs的目录依赖,即放在任何位置都可以执行,本节的例子和编译环境都必须放在nodejs的目录下,因为牵涉到路径的问题。
安装外部模块
首先我们要安装一个外部模块,该模块是Felix Geisend?rfer开发的node-formidable模块。它对解析上传的文件数据做了很好的抽象。 其实说白了,处理文件上传“就是”处理POST数据 —— 但是,麻烦的是在具体的处理细节,所以,这里采用现成的方案更合适点。
使用该模块,首先需要安装该模块。Node.js有它自己的包管理器,叫NPM。它可以让安装Node.js的外部模块变得非常方便。通过如下一条命令就可以完成该模块的安装:
1.先进入到nodejs的安装路径
cd C:\Program Files (x86)\nodejs
2.下载模块
npm install formidable
注:安装外部模块需要进入nodejs的根目录来执行npm指令
引用外部模块
现在我们就可以用formidable模块了——使用外部模块与内部模块类似,用require语句将其引入即可:
var formidable = require("formidable");
这里该模块做的就是将通过HTTP POST请求提交的表单,在Node.js中可以被解析。我们要做的就是创建一个新的IncomingForm,它是对提交表单的抽象表示,之后,就可以用它解析request对象,获取表单中需要的数据字段。
注:想要能引用到formidable,必须把你的项目放在nodejs的安装目录下,否则会出现下面的错误
requestHandlers的模块
应用程序需要新的部件,因此加入新的模块 -- 已经无需为此感到新奇了。我们来创建一个叫做requestHandlers的模块,并对于每一个请求处理程序,添加一个占位用函数,随后将这些函数作为模块的方法导出:
requestHandlers.js
varquerystring = require("querystring"),
fs = require("fs"),
formidable = require("formidable");
functionstart(response) {
console.log("Request handler 'start' was called.");
varbody =''+
'
'+'
'charset=UTF-8" />'+
''+
'
'+'
'method="post">'+
''+
''+
'
'+''+
'';
response.writeHead(200, {"Content-Type":"text/html"});
response.write(body);
response.end();
}
functionupload(response, request) {
console.log("Request handler 'upload' was called.");
varform =newformidable.IncomingForm();
console.log("about to parse");
form.parse(request,function(error, fields, files) {
console.log("parsing done");
console.log(files.upload.path);
//fs.renameSync(files.upload.path, "/tmp/test.png"); 这个会报错,这个应该是linux的路径
fs.renameSync(files.upload.path,"./upload/test.png");//winodw认的路径,nodejs的安装路径
//fs.renameSync(files.upload.path, "d:/tmp/test.png"); 这个也报错
response.writeHead(200, {"Content-Type":"text/html"});
response.write("received image:
");
response.write("");
response.end();
});
}
functionshow(response) {
console.log("Request handler 'show' was called.");
//winodw认的路径,nodejs的安装路径
fs.readFile("./upload/test.png","binary",function(error, file) {
if(error) {
response.writeHead(500, {"Content-Type":"text/plain"});
response.write(error +"\n");
response.end();
}else{
response.writeHead(200, {"Content-Type":"image/png"});
response.write(file,"binary");
response.end();
}
});
}
exports.start = start;
exports.upload = upload;
exports.show = show;
router模块
通过检查给定的路径对应的请求处理程序是否存在,如果存在的话直接调用相应的函数
router.js
functionroute(handle, pathname, response, request) {
console.log("About to route a request for "+ pathname);
if(typeofhandle[pathname] ==='function') {
handle[pathname](response, request);
}else{
console.log("No request handler found for "+ pathname);
response.writeHead(404, {"Content-Type":"text/html"});
response.write("404 Not found");
response.end();
}
}
exports.route = route;
server模块
处理请求模块
server.js
varhttp = require("http");
varurl = require("url");
functionstart(route, handle) {
functiononRequest(request, response) {
varpathname = url.parse(request.url).pathname;
console.log("Request for "+ pathname +" received.");
route(handle, pathname, response, request);
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;
index模块
启动模块,主模块
index.js
varserver = require("./server");
varrouter = require("./router");
varrequestHandlers = require("./requestHandlers");
varhandle = {}
//区分大小写的
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;
handle["/show"] = requestHandlers.show;
server.start(router.route, handle);
运行后效果
如果现在启动应用(node index.js,始终记得这个命令行),随后请求一个URL,我请求的分别是是http://localhost:8888/,上传文件提交后,页面就会显示该图片了,并且硬盘也会存在该文件。
硬盘中的文件
nodejs执行的结果
浏览器中显示的结果