我仍然难以理解如何向sails.js添加中间件。我听说过使用policies.js,创建自定义策略,添加到local.js等。所以有人可以告诉我如何将jquery-file-upload-middleware添加到sails应用程序中。提前致谢
答案 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
方法来覆盖所有中间件加载。参数是app
,defaultMiddleware
(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();
}
};
};