作者:秦乐0_707 | 来源:互联网 | 2023-05-19 05:18
一:环境说明1.1Linux系统CentOS5.8 1.2nodejsv0.10.15 1.3nodejs源码下载地址http:blog.nodejs.org 1.4
一:环境说明
1.1 Linux系统CentOS 5.8
1.2 nodejs v0.10.15
1.3 nodejs源码下载地址 http://blog.nodejs.org/
1.4 开发工具 WebStorm6 下载地址 http://www.jetbrains.com/webstorm/whatsnew/
二:安装配置
2.1 下载nodejs for linux (nodejs source)
2.2 nodejs安装过程中遇到的问题及解决方法 http://blog.csdn.net/code52/article/details/9036279
三:相关资料
3.1 入门学习资料 http://www.nodebeginner.org/index-zh-cn.html#blocking-and-non-blocking
3.2 API
3.2.1 英文API http://nodejs.org/api/
3.2.2 中英文对照 API http://docs.cnodejs.net/cman/
四:功能说明
4.1 参照3.1中提到的入门教程做的一个实现图片上传功能
4.2 在3.1中的学习资料中最后完成的是上传任何一张图片最后传到Linux中的都是叫test.png的图片,上传第二张图片的时候会把第一张图片替换掉
所以每次打开的都只是最新上传的那张图片
4.3 需求分析
在上述提到的学习资料中上传的没一张图片都命名为test.png,如果上传的图片是其他格式会不会有问题呢?假设没有问题,这样是否合理呢?
当然作为一个初学者可能不用考虑这么多东西,但是本着发散思维,深究问题的原则,做了以下修改
4.3.1 根据上传图片的后缀名来确定上传后文件的后缀名
4.3.2 上传图片不再使用test.png来命名,而且给上传的没一张图片都重新命名(在以往的实际开发过程中我们知道,多数情况下图片上传到服务器以后都不可能
以他上传时的名称作为上传后的名称),重命名的规则是随机生成一个10位数的数字作为其文件名,当然你还可以生成更大的随即数,这样重复的概率将会
更小,此文章的重点不在这里所以不做过多解释
4.3.3 获取已经上传的图片列表
4.3.4 当在列表中单机某一张图片的名称时,打开此图片
五:具体实现
5.1 server.js 服务器模块
/** * @auth solarstorm * @email solarstorm_java@sina.cn * @date 2013-8-19 10:44 * * 服务器模块 */ //导入http模块 var http = require('http'); //导入url模块 var url = require('url'); //导入querystring模块 var queryString = require('querystring'); /** * @param {Object} route router模块的route方法 */ function start(route, handle){ function onRequest(request, response){ //获取请求路径名称 var path = url.parse(request.url).pathname; //获取Get请求参数对象 var paramObj = url.parse(request.url).query; if (path != '/favicon.ico') { console.log('request for'+path+' receive.'); //请求转发 route(path, handle, response, request, paramObj); } } //创建服务器对象并监听8888端口 http.createServer(onRequest).listen(8888); console.log('Server to Started.'); } //输出start方法 exports.start = start;
5.2 router.js 路由模块
/** * 路由模块 * @auth solarstorm * @email solarstorm_java@sina.cn * @date 2013-8-19 10:44 * @param path 请求路径名称 * @param handle 请求路径数组 * @param response 浏览器相应对象 * @param request 浏览器请求对象 * @param paramObj Get请求方式中获取的请求路径中(?foo=123&val=8888)的部分 */ function route(path, handle, response, request, paramObj){ console.log('About to route a request for ' + path); if (typeof handle[path] === 'function') { handle[path](response, request, paramObj); }else { console.log("No request handler found for " + path); } } exports.route = route;
5.3 requestHandler.js 请求处理模块
/** * child_process : 子进程模块 * * 提供生成子进程的重要方法:child_process.spawn(command, args=[], [options]) * * 提供杀死进程的方法:child.kill(signal='SIGTERM') * * * 提供直接执行系统命令的重要方法:child_process.exec(command, [options], callback) * * exec的实现原理是启动了一个系统shell来解析参数,因此可以是非常复杂的命令,包括管道和重定向。 * 此外,exec还可以直接接受一个回调函数作为参数,回调函数有三个参数,分别是error, stdout, stderr * * options Object cwd String Current working directory of the child process env Object Environment key-value pairs encoding String (Default: 'utf8') timeout Number (Default: 0) maxBuffer Number (Default: 200*1024) killSignal String (Default: 'SIGTERM') return child_process object exec('find /',function(error, stdout, stderr){ response.writeHead(200, {'Content-Type' : 'text/plain'}); response.write(stdout); response.end(); }); */ /** * @author solarstorm * @email solarstorm_java@sina.cn * @date 2013-8-19 10:44 * * 请求处理模块 */ var exec = require('child_process').exec; var queryString = require('querystring'); var fs = require('fs'); var url = require('url'); //导入文件上传需要的模块 var formidable = require('formidable'); /** * 生成表单 * @param response */ function form(response) { console.log('start method...'); var body = ''+ ''+ ''+ ''+ ''+ ' '+ ' '+ ''+ ''+ ''+ ''; response.writeHead(200, {'Content-Type' : 'text/html'}); response.write(body); response.end(); } /** * 上传图片处理方法 * @param response * @param request */ function upload(response,request) { console.log("Request handler 'upload' was called."); //它是对提交表单的抽象表示,通过它就可以解析request对象,获取表单中需要的数据字段 var form = new formidable.IncomingForm(); form.parse(request,function(error,fields,files){ //生成一个10位数的随机码 var random = Math.floor(Math.random()*10000000000); //获取上传文件的名称,此处需要注意,这里的files.upload.name中的upload不是系统的属性,而是我们表单中name的名称 var name = files.upload.name; //截取文件名称找到后缀名 var suffix = name.substr(name.indexOf('.')); //上传文件,并修改文件名称 fs.renameSync(files.upload.path, '/upload/'+random+suffix); response.writeHead(200,{'Content-Type':'text/html;charset=UTF-8'}); response.write('上传成功...'); response.end(); }); } /** * 显示上传到图片库列表 * @param {Object} response * * fs.readdir(path, [callback]) * 异步调用readdir(3),读取目录中的内容。回调函数接受两个参数(err, files), * 其中files参数是保存了目录中所有文件名的数组('.'和'..'除外) * */ function displayList(response){ var dir = '/upload'; fs.readdir(dir, function(error, files){ response.writeHead(200, {"Content-Type": "text/html"}); var len = files.length; for (var i = 0; i response.write(""+files[i]+" "); } response.end(); }); } /** * 打开某一张图片 * @param {Object} response * @param {Object} request * @param {Object} paramObj 请求参数对象 * * fs.readFile(filename, [encoding], [callback]) 异步读取一个文件的所有内容 * 回调函数将传入两个参数(err, data),其中data为文件内容 * 如果没有设置编码,那么将返回原始内容格式的缓冲器 * */ function displayFileByName(response, request, paramObj){ //获取请求参数 var dir = queryString.parse(paramObj)['dir']; var img = queryString.parse(paramObj)['img']; fs.readFile(dir+'/'+img, 'binary', function(error, file){ if (!error) { response.writeHead(200, {"Content-Type": "image/jpeg"}); response.write(file, "binary"); response.end(); }else{ response.writeHead(500, {"Content-Type": "text/html"}); response.write(error + "\n"); response.end(); } }); } exports.form = form; exports.upload = upload; exports.displayList = displayList; exports.displayFileByName = displayFileByName;
5.4 index.js
/** * @auth solarstorm * @email solarstorm_java@sina.cn * @date 2013-8-19 10:44 */ var server = require('./server'); var router = require('./router'); var requestHandlers = require("./requestHandlers"); //定义一个路径数组,下标为请求路径,值为路径对应的请求处理方法 var handle = {}; handle['/'] = requestHandlers.form; handle['/form'] = requestHandlers.form; handle['/upload'] = requestHandlers.upload; handle['/displayList'] = requestHandlers.displayList; handle['/displayFileByName'] = requestHandlers.displayFileByName; server.start(router.route, handle);
六:效果图
6.1 上传界面
6.2 上传成功
6.3 上传图片列表
6.4 打开其中一张图片
七:总结
欢迎各位踊跃拍砖,有拍砖才有讨论,有讨论才有进步。