Как я могу использовать body-parser с LoopBack?

Я вижу, что LoopBack имеет встроенное промежуточное программное обеспечение Express 3.x. Действительно, body-parser находится в loopback/node_modules. Но я не могу понять, как использовать его в качестве промежуточного программного обеспечения. Я никогда не работал с Express 3.x, так что, возможно, это именно так. require не работает, очевидно, если я не установлю body-parser как зависимость в моем проекте.

Что мне делать в server.js для использования body-parser, чтобы веб-формы анализировались на 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."})
    });
}

Ответ 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.

Когда я отправляю сообщение в конечную точку, он теперь обрабатывается правильно, и все хорошо с миром. Надеюсь, это поможет кому-то еще!

Ответ 3

Я использую loopback 2.14.0:

Чтобы использовать тело-парсер в ваших настраиваемых маршрутах загрузки, вам нужно только:

1) установить body-parser npm install body-parser --save

2) Зарегистрируйте модуль в middleware.json

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

Нет необходимости требовать установки парсера в server.js, loopback делает это для вас, когда вы регистрируете промежуточное программное обеспечение.

Обратите внимание, что парсер тела теперь установлен в вашем исходном каталоге "node_modules", а также в каталоге модулей loopback.

Если это возможно, попробуйте зарегистрировать настраиваемые удаленные методы, как описано в loopback documentation.

Регистрация маршрутов таким образом дает вам доступ к body-parser loopback из коробки и является "самой чистой" реализацией.

Ответ 4

Я публикую это только для информационных целей. Я столкнулся с этой проблемой и нашел, что это работает. Вы можете добавить файл в каталог 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", так как они загружаются в алфавитном порядке.

Как я уже сказал, я считаю, что более корректно и элегантно использовать упомянутый выше подход к конфигурации промежуточного программного обеспечения, но я разделяю его в случае, если кто-то еще считает его полезным.

Ответ 5

У меня есть другой результат теста.

1) Для типов json и urlencode нет необходимости добавлять свой парсер в middleware.json. Я могу получить данные из req.body успешно без добавления body-parser # json и body-parser # urlencoded. 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) Для необработанного типа мы можем добавить body-parser # raw в "parse" часть в middleware.json, конечно, ему нужно npm установить 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",