0

I am using SuperAgent to test a Node/Express REST API.

Using .send, the body content is automatically converted to JSON. I would like to send plain text only. Here is an example:

request.post('localhost:3000/api/compile' )
        .send('my example text that gets converted to JSON')
        .set('Content-Type', 'application/x-www-form-urlencoded')

I have tried changing the Content-Type header, but still an object is sent.

How can I force SuperAgent to use plain text only?


UPDATE 1: Adding .type('form') as suggested still defaults to JSON.

request.post('localhost:3000/api/compile' )
        .type('form')
        .send('my example string')
        .set('Authorization', un+':'+key)
         //.set('Content-Type', 'application/x-www-form-urlencoded')
        .end(function(err, res){
                res.should.have.status(200);
                done();
        });

This gives -

 object
{ 'my example string': '' }

UPDATE 2: Adding backend code. Could this simply be Express?

app.js

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');
var api = require('./routes/api');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);
app.use('/api', api);

Route:

    router.post('/compile', function(req, res) {
      console.log(typeof(req.body));
      console.log(req.body);

      res.send('respond with a resource');
      res.end();

});

SOLUTION - remove BodyParser:

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var routes = require('./routes/index');
var users = require('./routes/users');
var api = require('./routes/api');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(favicon());
app.use(logger('dev'));
//app.use(bodyParser.json());
//app.use(bodyParser.urlencoded());

app.use (function(req, res, next) {
    var data='';
    req.setEncoding('utf8');
    req.on('data', function(chunk) {
        data += chunk;
    });
    req.on('end', function() {
        req.rawBody = data;
        next();
    });
});

app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', routes);
app.use('/users', users);
app.use('/api', api);
Ben
  • 6,026
  • 11
  • 51
  • 72
  • Show your server side code please. I think it is getting decoded automatically there. – Peter Lyons May 28 '14 at 03:46
  • @PeterLyons - I have added the Express backend - this is a default setup. I have also added the example route. Could this simply be the Express BodyParser? – Ben May 28 '14 at 15:38
  • Yes, it's the bodyParser has already parsed it back into json. That's what it does. To confirm, make your browser request in chrome with the developer tools open and find the request in the "Network" tab and you can accurately see there the true format the browser is sending. – Peter Lyons May 28 '14 at 15:41
  • Many thanks @PeterLyons. Yes, testing via a browser shows JSON. I have removed the BodyParser usage - see updated example above, so will test that out. Thanks again! – Ben May 28 '14 at 15:54
  • Are you looking at the "preview" tab? Don't use that one, you want to look at the raw request. I think it very likely that your code is working fine but your lack of familiarity with the tools and use of technical-but-not-truly-precise phrasing in your queston and comments is causing you all kinds of confusion. Post a screenshot of your dev tools request body or set up a plunkr so we can help properly. – Peter Lyons May 28 '14 at 16:09
  • Im using CURL and the Rest plugin for Chrome. Working great once the BodyParser is disabled. Thanks again. – Ben May 28 '14 at 23:19

1 Answers1

2

Use .type('form') to indicate you have data already in x-www-form-urlencoded format.

request.post('localhost:3000/api/compile')
  .type('form')
  .send('username=bob')

see the docs in the source here. There are a few other handy variations for x-www-form-urlencoded.

Your question has conflicting description vs code about text/plain vs. application/x-www-form-urlencoded, but if you want to really send plain text, it's .type('text/plain').

Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
  • Many thanks for the comments. I have tried adding .type('form') with the same results. I have tried many variations along with setting the content-type to text. Please see edits above. – Ben May 28 '14 at 03:25