web-dev-qa-db-fra.com

Comment utiliser un analyseur de corps avec LoopBack?

Je constate que LoopBack intègre le middleware Express 3.x. En effet, l'analyseur de corps est dans loopback/node_modules. Mais je n'arrive pas à comprendre comment l'utiliser comme middleware. Je n'ai jamais travaillé avec Express 3.x, alors c'est peut-être juste cela. require ne fonctionne évidemment pas, sauf si j'installe body-parser en tant que dépendance dans mon projet. 

Que dois-je faire dans server.js pour utiliser un analyseur de corps afin que les formulaires Web soient analysés dans req.params? C'est ce que ça fait, non?

20
Antrikshy

Après des heures de frustration, je l'ai simplement ajouté à middleware.json comme suit:

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

Il est installé en tant que dépendance. Maintenant, j'ai les données de formulaire dans req.body dans mes itinéraires. Mon server/boot/routes.js ressemble à ceci:

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."})
    });
}
49
Antrikshy

Juste pour être plus clair sur ce qu’il faut faire pour que cela fonctionne (parce que j’ai encore eu du mal après avoir trouvé cette réponse!), Voici les étapes que j’ai prises:

Comme décrit ci-dessus, dans $ APP_HOME/server/middleware.json, ajoutez l'analyseur de corps à la section "analyse":

{
  "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": {}
  }
}

Ensuite, j'ai ajouté la configuration de l'analyseur à $ 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

Puis, comme je ne voulais pas gâcher les itinéraires personnalisés, j’ai ajouté ceci à $ 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'}
    }
  );
};

Je peux maintenant exécuter mon application avec $> slc run. 

Lorsque je poste sur le terminal, tout est correctement analysé et tout va bien dans le monde. J'espère que ça aidera quelqu'un d'autre!

25
Ben Carlson

J'utilise loopback 2.14.0:

Pour utiliser l'analyseur de corps dans vos itinéraires de script de démarrage personnalisés, il vous suffit de:

1) installer body-parser npm install body-parser --save

2) Enregistrez le module dans middleware.json

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

Il n'est pas nécessaire de demander la configuration de l'analyseur dans server.js, le bouclage le fait pour vous lorsque vous enregistrez le middleware.

Veuillez noter que l'analyseur body est maintenant installé dans votre répertoire source "node_modules" ainsi que dans le répertoire des modules de bouclage.

Dans la mesure du possible, essayez d’enregistrer les méthodes distantes personnalisées, comme décrit dans la documentation loopback .

Enregistrer des itinéraires de cette manière vous donne accès à l'analyseur de corps de loopback dès l'installation et constitue l'implémentation la plus «propre». 

9
Lance

Sur la base de cette réponse https://stackoverflow.com/a/29813184/605586 de Ben Carlson, vous devez

npm install --save body-parser multer

alors dans votre server.js besoin des modules:

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

et les utiliser avant 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

Ensuite, vous pouvez créer une méthode distante:

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' }
    }
);

Grâce à cela, vous pouvez télécharger des fichiers et des champs de données supplémentaires à boucler avec multipart/form-data.

3
Thomas

Je poste ceci juste à titre informatif. J'ai rencontré le même problème et j'ai constaté que cela fonctionnait également. Vous pouvez ajouter un fichier dans le répertoire serveur/boot/avec les éléments suivants:

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

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

Bien sûr, vous devez installer le paquet en lançant:

npm install --save body-parser

Cela sauvegardera le paquet dans le répertoire node_modules . Si vous voulez que ce soit la première chose à exécuter, vous pouvez commencer le nom du fichier avec un "0" car ceux-ci sont chargés dans l'ordre alphabétique. 

Cela étant dit, je pense qu'il est plus "correct" et élégant d'utiliser l'approche de configuration de middleware mentionnée ci-dessus que celle-ci, mais je la partage si quelqu'un d'autre la trouvait utile.

2
David Welborn

On pourrait aussi utiliser l’analyseur intégré du cadre express à l’intérieur du bouclage comme ceci, par exemple pour l’analyse json: app.use(app.loopback.json());

0
ddsultan

J'ai un résultat de test différent.  

1) Pour les types json et urlencode, il n'est PAS nécessaire d'ajouter leur analyseur dans middleware.json. Je peux obtenir des données de req.body avec succès sans ajouter body-analyseur # json ni body-analyseur # urlencoded. Le Loopback devrait déjà les supporter.

Code source lié au bouclage (je pense)

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) Pour le type raw, nous pouvons ajouter body-parser # raw dans la partie "parse" de middleware.json, bien sûr, il faut que npm installent body-parser.  

Mon code de test: 

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",
0
caiyufei

Dans Loopback ^ 3.22.0, je peux suffire en ajoutant le 

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

au serveur/middleware.json afin de consommer les corps de poste application/json du serveur/boot/routes.js

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