Добавление пользовательского промежуточного программного обеспечения Express, такого как jQuery-File-Upload, в Sails.js

У меня все еще есть трудности с пониманием того, как добавить промежуточное программное обеспечение в sails.js. Я слышал, как использовать policy.js, создавать собственные политики, добавлять в local.js и т. Д. Итак, кто-то может показать мне, как именно я добавлю https://github.com/aguidrevitch/jquery-file-upload-middleware в приложение sails. заранее спасибо

2 ответа

Решение

Это было бы очень сложно в предыдущих версиях Sails, потому что вы не контролировали порядок, в котором было включено пользовательское промежуточное ПО. В версии 0.10 это довольно сложно.

Примечание: следующее будет работать с бета-версией Sails (v0.10.x), устанавливаемой через npm install sails@beta ,

Вставить ваше собственное промежуточное ПО в Sails так же просто, как добавить customMiddleware функция к вашему config/express.js файл, который принимает app в качестве аргумента; Вы можете тогда app.use к вашему сердцу. Недостатком этого подхода является то, что он не дает вам контроля над включением промежуточного программного обеспечения. Примечательно, что он включен после анализатора тела, который не будет работать в вашем случае.

В новейшей версии Sails вы можете переопределить всю загрузку промежуточного программного обеспечения, реализовав loadMiddleware метод в /config/express.js, Аргументы app, defaultMiddleware (набор функций промежуточного программного обеспечения, который Sails обычно включает по умолчанию), и sails (ссылка на глобальный объект Sails). Сначала рассмотрим реализацию ядра по умолчанию - вам, вероятно, захочется скопировать тот же порядок. Так в вашем /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...

}

Я думаю, что в случае загрузки файлов sails.js и jQuery вы можете заменить sails bodyParser на метод публикации файлов загрузки jQuery, идея из этой темы:

nginx / sails.js: загрузка файла не завершена

Приведенный ниже пример у меня работает нормально.паруса 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();
        }
    };
};
Другие вопросы по тегам