NodeJs upload files based on Express

来源:岁月联盟 编辑:exp 时间:2012-07-19

作为本blog的需求,上传图片始终是要支持的。但是呢,久久未动,以为麻烦,尽管诸多文章显示非常简单。昨天晚上终于下定决心解决它。果然简单异常,但是在本地测试成功之后发现部署到CloudFoundry却不能正常运行,原来还有小细节没有注意到。下面一一道来。

1. 准备工作
首先你要知道怎么用NodeJs下面的Web框架Express,这是一个比较简单、使用广泛的框架,入门很简单。本ramonblog就是用它搭建的。Express的View是用jade语法的,这个你也得懂一点。是不是学的东西有点多了?不用太理解,开始的时候都是抄的,抄得多也就懂了。

然后呢,我们就用可以准备我们的upload.jade了,这里仅仅是包含了一个简单的表单,里面一个file input元素和一个submit元素。

div
    form(method="post", enctype="multipart/form-data")
        input(type="file", name="displayImage")
        input(type="submit", name="submit", value="Submit")
2. 让它工作吧
之所以Express底下上传文件非常简单,是因为Express的bodyParser中间件会在解析request请求的时候,将“multipart/form-data”里面的file input对应的内容自动处理保存到默认的/tmp文件夹下面,而你可以通过req.files来获取所有的属性,其内容大概如下:

{ displayImage:
    {
    size: 18925,
    path: '/tmp/47662e4853761e4b30b6c3a329980dac',
    name: '2.jpg',
    type: 'image/jpeg',
    lastModifiedDate: Wed, 18 Jul 2012 17:01:44 GMT,
    _writeStream:
        { path: '/tmp/47662e4853761e4b30b6c3a329980dac',
        fd: 36,
        writable: false,
        flags: 'w',
        encoding: 'binary',
        mode: 438,
        bytesWritten: 18925,
        busy: false,
        _queue: [],
    drainable: true },
        length: [Getter],
        filename: [Getter],
        mime: [Getter]
        }
    }
}
注意其中的displayImage是我们在form中定义的file的name,req.files.displayImage的path表示在服务器端的临时地址,name表示上传的原始文件名称,type则是文件类型了。提交之后的处理则如下:

var fs = require('fs');
var path = require('path');

function(req, res) {

    //你可能需要修改相关的newPath到你自己的地址
    var filePath = req.files.displayImage.path;
        var extName = path.extname(req.files.displayImage.name);
        var imageUrl = "/upload/" + path.basename(filePath) + extName;
        var newPath = __dirname + "/../public" + imageUrl;

    //把图片从临时文件夹复制到目的文件夹,当然最好删除临时文件
        fs.readFile(filePath, function (err, data) {
            if (err) {
                res.send(err);
                return;
            }

            fs.writeFile(newPath, data, function (err) {
                if (!err) {
                    res.send({uploaded: true});
                } else {
                    res.send(err);
                }
            });
        });
}
注意,你可能需要自己修改newPath到你自己正确的地址。其次,如果想直接访问你上传的图片,需要把图片放置在Express指定的public文件夹下面,这样可以直接通过链接访问。

3. CloudFoundry上不能工作   www.2cto.com
很显然在CF的服务器上你不能写文件到 /tmp下面去。其实解决办法也很简单,就是把临时文件夹指定到你自己的应用下面去。譬如指定为应用下面的tmp文件夹,需要做的就是在你的app.js中增加如下的i配置:

app.use(express.bodyParser({
        uploadDir: __dirname + '/tmp'
}));
这里要求的app.js就在应用的根目录下,这样__dirname就会是你的应用根目录。之后你就可以在CF上执行上传图片了。

 

作者:llmlx