luxh

  图片上传请求由Node处理,图片访问请求由Nginx处理。

1、Nginx配置

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  \'$remote_addr - $remote_user [$time_local] "$request" \'
    #                  \'$status $body_bytes_sent "$http_referer" \'
    #                  \'"$http_user_agent" "$http_x_forwarded_for"\';

    #access_log  logs/access.log  main;

    sendfile        on;
    tcp_nopush     on;
    sendfile_max_chunk 256K;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;
    
    upstream localhost {
        server localhost:3000;#node服务器
    }

    server {
        listen       80;
        server_name  localhost;
        
        
        #开启索引功能
        autoindex    on;
        
        #关闭计算文件确切大小
        autoindex_exact_size off;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        #上传操作由node服务器处理
        location / {
            proxy_pass    http://localhost;
            index    index.html;
        }
        
        #映射图片访问url
        location /image/ {
            expires 30d;#缓存时间
            root    E:/Study/nginx/nginx-1.7.6/files;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache\'s document root
        # concurs with nginx\'s one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}
View Code

 

2、nodejs项目架构

  1)项目结构图

  2)bin/www 是启动脚本

#!/usr/bin/env node
var debug = require(\'debug\')(\'file-server\');
var app = require(\'../app\');

app.set(\'port\', process.env.PORT || 3000);

var server = app.listen(app.get(\'port\'), function() {
  console.log(\'Express server listening on port \' + server.address().port);
  debug(\'Express server listening on port \' + server.address().port);
});

  3)config/setting.json 是程序中用的一些常量以json格式配置

{
    "image_url":"http://localhost/image",
    "image_dir":"E:/Study/nginx/nginx-1.7.6/files/image",
    "tmp_dir":"E:/Study/nginx/nginx-1.7.6/tmp"
}

  4)controller/file-ctrl.js 是文件上传的处理代码

var fs = require(\'fs\');
var path = require(\'path\');
var    formidable = require(\'formidable\');
var util = require(\'util\');
var fs = require(\'fs\');
var path = require(\'path\');

var setting = require(\'../config/setting.json\');




/**
 * 上传
 */
exports.upload = function(req,res){

    var form = new formidable.IncomingForm();
    form.encoding = \'utf-8\';

    //如果需要临时文件保持原始文件扩展名,设置为true
    form.keepExtensions = false;

    //文件大小限制,默认2MB
    form.maxFieldsSize = 2 * 1024 * 1024;


    //图片存放目录
    var imageDir = setting.image_dir;

    //上传临时目录
    var tmpDir = setting.tmp_dir;

    form.uploadDir = tmpDir;//目录需要已存在
    /**
     * fields 表单中的其他属性
     * files  文件集合
     */
    form.parse(req, function(err, fields, files) {

        //图片完整路径
        var imagePath = path.resolve(imageDir, files.file.name);


        //将临时目录中的图片移动到图片存放目录下
        fs.rename(files.file.path,imagePath,function(err){
            if(err) {
                res.json({\'success\':false,\'msg\':err});
            }else{
                var image_url = setting.image_url+\'/\'+files.file.name;
                res.json({\'success\':true,\'msg\':\'上传成功!\',\'image_url\':image_url});
                //res.json({\'success\':true,\'msg\':\'上传成功!\',\'image_url\':image_url,\'fields\':util.inspect({fields: fields, files: files})});
            }
        });
    });
}




/**
 * 下载
 */
exports.download = function(req,res){
    var filename = req.params.filename;
    var dir = setting.file_dir;
    var file_path = path.resolve(dir,filename);
    fs.exists(file_path,function(exists) {
        if(!exists) {
            res.json({\'success\':false,\'msg\':\'文件不存在!\'});
        }else{
            res.download(file_path,function(err){
                if(err) {
                    res.json({\'success\':false,\'msg\':err});
                }
            });
            
        }
    });    
}

  5)routes/route.js 是整个项目的路由控制

var express = require(\'express\');
var router = express.Router();

var file_ctrl = require(\'../controller/file-ctrl\')

/**上传文件*/
router.post(\'/upload\',file_ctrl.upload);

module.exports = router;

  6)app.js 是项目的全局配置

var express = require(\'express\');
var path = require(\'path\');
var favicon = require(\'static-favicon\');
var logger = require(\'morgan\');
var cookieParser = require(\'cookie-parser\');
var bodyParser = require(\'body-parser\');

var routes = require(\'./routes/route\');

var app = express();

// view engine setup
app.set(\'views\', path.join(__dirname, \'views\'));
app.set(\'view engine\', \'jade\');

app.use(favicon());
app.use(logger(\'dev\'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, \'public\')));

app.use(\'/\', routes);

/// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error(\'Not Found\');
    err.status = 404;
    next(err);
});

/// error handlers

// development error handler
// will print stacktrace
if (app.get(\'env\') === \'development\') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render(\'error\', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render(\'error\', {
        message: err.message,
        error: {}
    });
});


module.exports = app;

  6)package.json  是依赖包管理

{
  "name": "file-server",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "express": "~4.2.0",
    "static-favicon": "~1.0.0",
    "morgan": "~1.0.0",
    "cookie-parser": "~1.0.1",
    "body-parser": "~1.0.0",
    "debug": "~0.7.4",
    "jade": "~1.3.0",
    "formidable":"*"
  }
}

 

  项目用到了expressjs框架。

 

3、简单写一个html上传页面

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    
    <title>upload</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>
  
  <body>
        <form action="http://localhost/upload" method="post" enctype="multipart/form-data">
            <input type="file" name="file">
            <p>
            <input type="submit" value="上传">
        </form>
  </body>
</html>

 

4、启动node服务器和Nginx服务器

  进入项目根目录,执行 node bin\www  或 npm start (这个是在package.json中配置的脚本命令"scripts")

 

5、测试

  1)上传图片

  2)上传成功

  

 

  3)直接访问image_url就可以看到图片了

分类:

技术点:

相关文章: