zoukankan      html  css  js  c++  java
  • node.js系列笔记之node.js初识《一》

    node.js系列笔记之node.js初识《一》

    一:环境说明

      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 = '<html>'+
                   '<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />'+
                   '<head>'+
                   '<body>'+
                   '<form action = "/upload" method="post" enctype="multipart/form-data">'+
                   '<input type="file" name="upload">'+
                   '<input type="submit" value="submit">'+
                   '</form>'+
                   '</boyd>'+
                   '<head>'+
                   '</html>';

        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 < len; i ++) {
                response.write("<a href='/displayFileByName?dir="+dir+"&img="+files[i]+"'>"+files[i]+"</a><br/>");
            }

            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 + " ");
                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 打开其中一张图片

        

        

    七:总结

      欢迎各位踊跃拍砖,有拍砖才有讨论,有讨论才有进步。

     
     
    分类: node.js
  • 相关阅读:
    SpringBoot 之Spring Boot Starter依赖包及作用
    WebApi过滤器使用和请求实体合法性验证
    sql server 事务隔离性 snapshot 、read committed说明
    jQuery的deferred对象详解
    Juqery插件编写 基础说明
    sqlServer MERGE 对数据进行修改或插入自动视别 特别用于批量数据的插入或修改
    .net EntityFramework dbContext 如何实例化
    NOPI Excel 数据导入到数据库
    知识点整理01- 引用对象被子方法赋值后不改变;CheckBox 取消选择不可用问题
    .net Windows Service 按装及遇到的问题
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3280593.html
Copyright © 2011-2022 走看看