如何将 body-parser 与 LoopBack 一起使用?

Posted

技术标签:

【中文标题】如何将 body-parser 与 LoopBack 一起使用?【英文标题】:How can I use body-parser with LoopBack? 【发布时间】:2015-04-15 22:08:16 【问题描述】:

我看到 LoopBack 内置了 Express 3.x 中间件。事实上,body-parser 在loopback/node_modules 中。但我不知道如何将它用作中间件。我从未使用过 Express 3.x,所以也许就是这样。 require 显然不起作用,除非我在我的项目中安装 body-parser 作为依赖项。

我应该在server.js 中做什么才能使用body-parser 以便将Web 表单解析为req.params?这就是它的作用,对吧?

【问题讨论】:

【参考方案1】:

经过几个小时的挫折后,我刚刚将其添加到middleware.json,如下所示:

"parse": 
    "body-parser#json": ,
    "body-parser#urlencoded": "params":  "extended": true 

它作为依赖项安装。现在我的路线中有req.body 中的表单数据。我的server/boot/routes.js 看起来像这样:

module.exports = function(app) 
    app.post('/mailing_list', function(req, res) 
        console.log(req.body.email);
        res.send("status": 1, "message": "Successfully added to mailing list.")
    );

【讨论】:

你是怎么算出来的?文档在哪里? 从那以后已经有很长时间了,但我认为我在 Express.js 方面的一点经验在我尝试各种配置排列时有所帮助。 谢谢兄弟,你拯救了我的一天。 经过半小时的研究,我看到了你的答案和完美的答案。 @Antrikshy 如何使用环回 4 执行此操作?【参考方案2】:

只是为了更清楚地了解如何使这个工作正常(因为我在找到这个答案后仍然挣扎了一段时间!),以下是我采取的步骤:

如上所述,在 $APP_HOME/server/middleware.json 中,将 body-parser 添加到“parse”部分:


  "initial:before": 
    "loopback#favicon": 
  ,
  "initial": 
    "compression": ,
    "cors": 
      "params": 
        "origin": true,
        "credentials": true,
        "maxAge": 86400
      
    
  ,
  "session": 
  ,
  "auth": 
  ,
  "parse": 
    "body-parser#json": ,
    "body-parser#urlencoded": "params":  "extended": true 
  ,
  "routes": 
  ,
  "files": 
  ,
  "final": 
    "loopback#urlNotFound": 
  ,
  "final:after": 
    "errorhandler": 
  

接下来,我将解析器设置添加到 $APP_HOME/server/server.js:

var loopback = require('loopback');
var bodyParser = require('body-parser');
var multer = require('multer');

var boot = require('loopback-boot');

var app = module.exports = loopback();

app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded( extended: true )); // for parsing application/x-www-form-urlencoded
app.use(multer()); // for parsing multipart/form-data

app.start = function() 
...
...
cont'd

然后,因为我不想弄乱自定义路由,所以我在 $APP_HOME/common/models/model.js 中添加了以下内容:

module.exports = function(Model) 

  Model.incoming = function(req, cb) 
    cb(null, 'Hey there, ' + req.body.sender);
  
  Model.remoteMethod(
    'incoming',
     accepts: [
       arg: 'req', type: 'object', http: function(ctx) 
        return ctx.req;
       
    ],
    returns: arg: 'summary', type: 'string'
    
  );
;

我现在可以使用 $> slc run 运行我的应用程序。

当我发布到端点时,它现在被正确解析,一切都很好。我希望这对其他人有帮助!

【讨论】:

你先生,是个传奇。 谢谢你;被困在这几个小时了! 应该被接受的答案。为我工作!谢谢@Ben Carlson 这甚至没有为我启动。具体来说,这行:app.use(multer()); // for parsing multipart/form-data 不起作用,除非我添加了一个函数 multer().any() - 否则会出现错误 equires middleware functions 如其他 cmets 中所述,您无需在 server.js 和 middleware.json 中指定解析配置。后者是首选方法。【参考方案3】:

我正在使用环回 2.14.0:

要在自定义引导脚本路由中使用正文解析器,您只需:

1) 安装正文解析器 npm install body-parser --save

2) 在 middleware.json 中注册模块

"parse": 
"body-parser#json": ,
"body-parser#urlencoded": "params":  "extended": true 
,

server.js 中不需要设置解析器,在注册中间件时,loopback 会为您完成。

请注意,body 解析器现在安装在您的源“node_modules”目录以及环回模块目录中。

如果可能,请尝试按照loopback documentation 中的说明注册自定义远程方法。

以这种方式注册路由可以让您开箱即用地访问环回的正文解析器,并且是“最干净”的实现。

【讨论】:

【参考方案4】:

根据 Ben Carlson 的回答 https://***.com/a/29813184/605586,您必须这样做

npm install --save body-parser multer

然后在你的 server.js 中需要模块:

var bodyParser = require('body-parser');
var multer = require('multer');

并在 app.start 之前使用它们:

app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded( extended: true )); // for parsing application/x-www-form-urlencoded
app.use(multer().any()); // for parsing multipart/form-data

然后你可以创建一个远程方法:

App.incoming = function (req, cb) 
    console.log(req);
    // the files are available as req.files.
    // the body fields are available in req.body
    cb(null, 'Hey there, ' + req.body.sender);

App.remoteMethod(
    'incoming',
    
    accepts: [
        
        arg: 'req', type: 'object', http: function (ctx) 
            return ctx.req;
        
        ],
    returns:  arg: 'summary', type: 'string' 
    
);

使用它,您可以上传文件和其他数据字段以使用 multipart/form-data 进行环回。

【讨论】:

【参考方案5】:

我发布这个只是为了提供信息。我遇到了同样的问题,发现这也有效。您可以使用以下内容在 server/boot/ 目录中添加文件:

var bodyParser = require('body-parser');

module.exports = function(app) 
  app.use(bodyParser.urlencoded( extended: true ));

当然,你必须通过运行来安装包:

npm install --save body-parser

这会将包保存在 node_modules 目录下。 如果您希望它首先运行,您可以以“0”开头的文件名,因为它们是按字母顺序加载的。

话虽如此,我认为使用上面提到的中间件配置方法比这个更“正确”和优雅,但如果其他人觉得它有用,我会分享它。

【讨论】:

【参考方案6】:

在 Loopback ^3.22.0 中,我可以通过添加

"parse": 
    "body-parser#json": 
  ,

到服务器/middleware.json 为了使用 server/boot/routes.js 中的 application/json post body

module.exports = function(app) 
  app.post('/api/sayhello', function(req, res, next) 
     console.log(req.body)

【讨论】:

【参考方案7】:

我有不同的测试结果。

1) 对于 json 和 urlencode 类型,不需要在 middleware.json 中添加它们的解析器。我可以在不添加 body-parser#json 和 body-parser#urlencoded 的情况下成功从 req.body 获取数据。 Loopback 应该已经支持它们了。

Loopback相关源码(我认为)

1. in strong-remote repo , rest-adapter.js , there is body-parser for json and urlendcoded

line 35
var json = bodyParser.json;
var urlencoded = bodyParser.urlencoded;

line 315
root.use(urlencoded(urlencodedOptions));
root.use(json(jsonOptions));

2. 
remote-object.js
line 33
require('./rest-adapter');

line 97
RemoteObjects.prototype.handler = function(nameOrClass, options) 
var Adapter = this.adapter(nameOrClass);
var adapter = new Adapter(this, options);
var handler = adapter.createHandler();

if (handler) 
// allow adapter reference from handler
handler.adapter = adapter;


return handler;
;

2)对于raw类型,我们可以在middleware.json的“parse”部分添加body-parser#raw,当然需要npm install body-parser。

我的测试代码:

1.My readable stream is from the file uploadRaw.txt , the content is :
GreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaGreenTeaEeeeend

2. middleware.json
"parse": 
"body-parser#raw": 
"paths": [
"/api/v1/Buckets/?/upload"
]

,

3.
it('application/octet-stream -- upload non-form', () =>
new Promise((resolve) => 

const options = 

method: 'POST',

host: testConfig.server.host,

port: testConfig.server.port,

path: $appconfig.restApiRoot/Buckets/$TEST_CONTAINER/upload,

headers: 

'Content-Type': 'application/octet-stream',

,
;

const request = http.request(options);

request.on('error', (e) => 
logger.debug(problem with request: $e.message);
);

const readStream = fs.createReadStream('tests/resources/uploadRaw.txt');

readStream.pipe(request);

resolve();
));

4.
Bucket.upload = (req, res, options, cb) => 

logger.debug('sssssss in uploadFileToContainer');

fs.writeFile('/Users/caiyufei/TEA/green.txt', req.body, (err) => 

if (err) 

logger.debug('oh, failed to write file');

return;


logger.debug('green file is saved!');
);

;

OR

Bucket.upload = (req, res, options, cb) => 

logger.debug('sssssss in uploadFileToContainer');

const writeStream = fs.createWriteStream('/Users/caiyufei/TEA/green.txt');

const streamOptions = 
highWaterMark: 16384,`enter code here`
encoding: null,


streamifier.createReadStream(Buffer.from(req.body), streamOptions).pipe(writeStream);

;

5. package.json

"body-parser": "^1.17.1",

"streamifier": "^0.1.1",

【讨论】:

【参考方案8】:

也可以像这样在loopback内部使用express框架的内置解析器,例如json解析: app.use(app.loopback.json());

【讨论】:

以上是关于如何将 body-parser 与 LoopBack 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

body-parser 是一个Http请求体解析中间件

关于AngularJS中$http跨域 与 nodejs接收跨域请求(使用express-session,body-parser)的设置

如何在快速路由器中使用正文解析器?

不推荐使用获取 body-Parser 警告在 Vs 代码中并且无法获取 Body 尝试使用 express 的内置 body-parser

实验九 ACL的应用

[转] Nodejs 进阶:Express 常用中间件 body-parser 实现解析