rahul
rahul

Reputation: 930

how to post data in node.js with content type ='application/x-www-form-urlencoded'

I'm having a problem in posting data in node.js with Content-type: 'application/x-www-form-urlencoded'

var loginArgs = {
    data: 'username="xyzzzzz"&"password="abc12345#"',

    //data: {
    //    'username': "xyzzzzz",
    //    'password': "abc12345#",
    //},

    headers: {
            'User-Agent': 'MYAPI',
            'Accept': 'application/json',
            'Content-Type':'application/x-www-form-urlencoded'      
    }   
};

And post request is:

client.post("http:/url/rest/login", loginArgs, function(data, response){
console.log(loginArgs);

if (response.statusCode == 200) {
    console.log('succesfully logged in, session:', data.msg);
}

It always returns username/password incorrect.

In the rest api it is said that the request body should be:

username='provide user name in url encoded
format'&password= "provide password in url encoded format'

Upvotes: 42

Views: 101064

Answers (7)

Doug Coburn
Doug Coburn

Reputation: 2575

use Node's querystring library to encode data in application/x-www-form-urlencoded format before passing it as the body to your REST request.

I'm not sure what library you are using (jQuery?) but it looks like you should be able to call it like this:

const querystring = require('node:querystring'); 
const loginArgs = {
  data: querystring.stringify({
    'username': "xyzzzzz",
    'password': "abc12345#",
  }),
  headers: {
    'User-Agent': 'MYAPI',
    'Accept': 'application/json',
    'Content-Type':'application/x-www-form-urlencoded'      
  }
};
client.post(
  "http:/url/rest/login",
  loginArgs,
  function(data, response) {
    console.log(loginArgs);
    if (response.statusCode == 200) {
      console.log('succesfully logged in, session:', data.msg);
    }
  }
}

assuming that this client.post takes an object as it's 2nd argument where the data property is a string to use as the REST body.

Upvotes: 0

David Chaiken
David Chaiken

Reputation: 41

I think that the got package has built-in functionality that works:

const got = require('got');

const response = await got.post(url, {form: {a: 'd', b: 'b', c: 'c'});

Upvotes: 4

Use node's URLSearchParams class to encode the js object to "url encoded" form and pass the string as the request body. Documentation

Upvotes: 7

Ilyes
Ilyes

Reputation: 41

If you are using got package

const got = require('got');
const qs = require('qs');

const body = qs.stringify({
    a: 'd',
    b: 'b',
    c: 'c',
});

In async function

const response = await got.post(url, { body });

If the Content-Type header is not present, it will be set to application/x-www-form-urlencoded

Upvotes: 2

KeaganFouche
KeaganFouche

Reputation: 681

application/x-www-form-urlencoded requires that you URL encode your Key and Values (MSDN Documentation). For illustration:

data:`${encodeURI('username')}=${encodeURI('xyzzzzz')}&${encodeURI('password')}=${encodeURI('abc12345')}`

Request Library has been deprecated, as commented by @Bram.

The example I will write will use the standard HTTPS library which comes with NodeJS.
You could write it as the following (in typescript):

import * as https from 'https';
// import * as http from 'http'; // For HTTP instead of HTTPS

export class ApiExample {

    // tslint:disable-next-line: no-empty
    constructor() { }

    public async postLogin(username: string, password: string): Promise<any> {
        // application/x-www-form-urlencoded requires the syntax "UrlEncodedKey=UrlEncodedValue&UrlEncodedKey2=UrlEncodedValue2"
        const xFormBody = `${encodeURI('username')}=${encodeURI(username)}&${encodeURI('password')}=${encodeURI(password)}`;

        return this.performRequest(xFormBody)
    }

    private performRequest(requestBody: string) {
        return new Promise((resolve, reject) => {

            const options: https.RequestOptions = {
                hostname: 'example.url.com',
                port: 443,
                path: '/login',
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Content-Length': Buffer.byteLength(requestBody)
                }
            };

            // const req = http.request(options, function (res) { // For HTTP
            const req = https.request(options, function (res) {
                // This may need to be modified based on your server's response.
                res.setEncoding('utf8');

                let responseBody = '';

                // Build JSON string from response chunks.
                res.on('data', (chunk) => responseBody = responseBody + chunk);
                res.on('end', function () {
                    const parsedBody = JSON.parse(responseBody + '');

                    // Resolve or reject based on status code.
                    res.statusCode !== 200 ? reject(parsedBody) : resolve(parsedBody);
                });
            });

            // Make sure to write the request body.
            req.write(requestBody);
            req.end();
            req.on('error', function (e) { reject(e); });
        });
    }
}

export default ApiExample;

Upvotes: 19

Husain Ali
Husain Ali

Reputation: 165

If you are using axios package, Here is the solution.

If you have the headers as Content-type: 'application/x-www-form-urlencoded'

then you will call post API as

const response: any = await axios.post(URL, bodyData,  {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            });

URL is you API url like http//YOUR_HOST/XYZ..., and

bodyData is the data which you want to send in post API,

Now how will you pass it ?

Suppose you have data as object, so you have to encode it as url, let me show you

let data = {
username: name,
password: password
}

then your bodyData will be like

let bodyData = `username=${name}&password=${password}`

This is the way you can pass your data in body if header is Content-type: 'application/x-www-form-urlencoded'

If you have a huge data which you cannot encode it manually then you can use qs module

run command npm i qs and in your file

const qs = require('qs');

...

let data = {
username: name,
password: password,
manyMoreKeys: manyMoreValues
} 
 
let bodyData = qs.stringify(data);

Upvotes: 5

Eduardo Cuomo
Eduardo Cuomo

Reputation: 18937

request supports application/x-www-form-urlencoded and multipart/form-data form uploads. For multipart/related refer to the multipart API.

application/x-www-form-urlencoded (URL-Encoded Forms)

URL-encoded forms are simple:

const request = require('request');

request.post('http:/url/rest/login', {
  form: {
    username: 'xyzzzzz',
    password: 'abc12345#'
  }
})
// or
request.post('http:/url/rest/login').form({
  username: 'xyzzzzz',
  password: 'abc12345#'
})
// or
request.post({
  url: 'http:/url/rest/login',
  form: {
    username: 'xyzzzzz',
    password: 'abc12345#'
  }
}, function (err, httpResponse, body) { /* ... */ })

See: https://github.com/request/request#forms

Or, using request-promise

const rp = require('request-promise');
rp.post('http:/url/rest/login', {
  form: {
    username: 'xyzzzzz',
    password: 'abc12345#'
  }
}).then(...);

See: https://github.com/request/request-promise#api-in-detail

Upvotes: 42

Related Questions