将自定义Express中间件(如jQuery-File-Upload)添加到Sails.js

时间:2014-02-21 16:29:41

标签: node.js sails.js

我仍然难以理解如何向sails.js添加中间件。我听说过使用policies.js,创建自定义策略,添加到local.js等。所以有人可以告诉我如何将jquery-file-upload-middleware添加到sails应用程序中。提前致谢

2 个答案:

答案 0 :(得分:14)

在Sails的早期版本中,这将非常困难,因为您无法控制包含自定义中间件的顺序。在v0.10中,它只是有点很难。

注意:以下内容适用于beta version of Sails (v0.10.x),可通过npm install sails@beta安装。

将自己的自定义中间件插入Sails就像在customMiddleware文件中添加config/express.js函数一样简单,该文件以app为参数;然后,您可以app.use了解您的内心。这种方法的缺点是,当包含中间件时,它无法控制。值得注意的是,它包含在身体解析器之后的,这对你的情况不起作用。

在最新版本的Sails中,您可以通过在loadMiddleware中实施/config/express.js方法来覆盖所有中间件加载。参数是appdefaultMiddleware(Sails通常默认包含的中间件函数集)和sails(对全局Sails对象的引用)。首先看一下the default core implementation - 你可能想要复制相同的订单。所以在你的/config/express.js中,你会有类似的东西:

var upload = require('jquery-file-upload-middleware');

// configure upload middleware
upload.configure({
    uploadDir: __dirname + '/public/uploads',
    uploadUrl: '/uploads',
    imageVersions: {
        thumbnail: {
            width: 80,
            height: 80
        }
    }
});

module.exports.express = {

    loadMiddleware: function(app, defaultMiddleware, sails) {

        // Use the middleware in the correct order
        app.use(defaultMiddleware.startRequestTimer);
        app.use(defaultMiddleware.cookieParser);
        app.use(defaultMiddleware.session);
        // Insert upload file handler
        app.use('/upload', upload.fileHandler());
        app.use(defaultMiddleware.bodyParser);
        app.use(defaultMiddleware.handleBodyParserError);
        app.use(defaultMiddleware.methodOverride);
        app.use(defaultMiddleware.poweredBy);
        app.use(defaultMiddleware.router);
        app.use(defaultMiddleware.www);
        app.use(defaultMiddleware.favicon);
        app.use(defaultMiddleware[404]);
        app.use(defaultMiddleware[500]);
    }

    ...etc...

}

答案 1 :(得分:3)

在sails.js和jQuery文件上传的情况下我认为,您可以将sails bodyParser替换为jQuery文件上传器post方法,来自这个帖子的想法:

nginx / sails.js: incomplete file upload

以下示例对我很有用。 sails js 0.10.5

npm install blueimp-file-upload-expressjs --save
npm install lodash --save

取消注释并在 /config/http.js 文件中添加行:

middleware: {

       cbodyParser: require('../cbodyParser')( { urls: [/\/uploads/]} ),

    order: [
       'startRequestTimer',
       'cookieParser',
       'session',
       'myRequestLogger',

       'cbodyParser',       // intersept multipart requests
       'bodyParser',

       'handleBodyParserError',
       'compress',
       'methodOverride',
       'poweredBy',
       '$custom',
       'router',
       'www',
       'favicon',
       '404',
       '500'
    ]
}

根文件夹 /cbodyParser.js 中的新文件:

var _ = require('lodash');

var options = {
    tmpDir:  __dirname + '/uploads/tmp',
    publicDir: __dirname + '/uploads',
    uploadDir: __dirname + '/uploads',
    uploadUrl:  '/uploads/',
    maxPostSize: 11000000000, // 11 GB
    minFileSize:  1,
    maxFileSize:  10000000000, // 10 GB
    acceptFileTypes:  /.+/i,
    inlineFileTypes:  /\.(gif|jpe?g|png)$/i,
    imageTypes:  /\.(gif|jpe?g|png)$/i,
    imageVersions: {
        width:  220,
        height: 220
    },
    accessControl: {
        allowOrigin: '*',
        allowMethods: 'POST',
        allowHeaders: 'Content-Type, Content-Range, Content-Disposition'
    },
    nodeStatic: {
        cache:  3600 // seconds to cache served files
    }
};

var uploader = require('blueimp-file-upload-expressjs')(options);

function mime(req) {
    var str = req.headers['content-type'] || '';
    return str.split(';')[0];
}

// start jQuery file uploader here:
function parseMultipart(req, res, next) {

    uploader.post(req, res, function (obj) {
        res.send(JSON.stringify(obj));
    });

    next();

}

// check for post method in request
function disable_parser(opts, req, res)  {
    var matched = false;
    try {
        var method = null;
        try {method = req.method.toLowerCase();}
        catch(err){ /* */}
        if(method) {
            _(opts.urls).forEach(function(turl) {
                if (method === 'post' && req.url.match(turl)) {
                    // console.log("matched"+ req.url);
                    if(!matched) matched = true;
                };});
        }
    } catch(err) { debug(err);/* pass */ }
    return matched;
}


// Start all stuff..
module.exports = function toParseHTTPBody(options) {
    options = options || {};

    // NAME of anynonymous func IS IMPORTANT (same as the middleware in config) !!!
    return function cbodyParser(req, res, next) {
        if (disable_parser(options, req, res) && mime(req) == 'multipart/form-data') {  
            // we found multipart request to /uploads, so we can use jQuery file uploader instead
            return parseMultipart(req, res, next);    
        } else {
            return next();
        }
    };
};