Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

axios.post() requests do not send headers and payload as expected #827

Closed
jsalerno opened this issue Apr 8, 2017 · 6 comments
Closed

axios.post() requests do not send headers and payload as expected #827

jsalerno opened this issue Apr 8, 2017 · 6 comments

Comments

@jsalerno
Copy link

jsalerno commented Apr 8, 2017

The Axios .post() function is not working as I expected it to.

Sitting on the serverside Java debugger I have grabbed the MimeHeader's sent to the server by Axios and also by (ubuntu) cURL.
The java server-side class is org.apache.catalina.connector.CoyoteAdapter.
The debugger is in the service(Request, Response) method (version tomcat-embed-core-8.5.6.jar, line: 308).

I issued 3 'login' requests and compared the results.

  1. cURL, which works as expected
  2. AXIOS, using textual field names in the .post call
  3. AXIOS, using named fields in the .post call
    Neither of the 2 Axios calls sends the request as I expect it should do.

Here is the CURL:
curl -X POST -vu webui:webuisecret http://localhost:8081/merchant/oauth/token -k -H "Accept: application/json" -d "password=merchant1&username=merchant1&grant_type=password&scope=read%20write&client_secret=webuisecret&client_id=webui"

and here are captured the

=== MimeHeaders ===
host = localhost:8081
authorization = Basic d2VidWk6d2VidWlzZWNyZXQ=
user-agent = curl/7.47.0
accept = application/json
content-length = 118
content-type = application/x-www-form-urlencoded

All good so far.

[AXIOS - TEXT NAMES]
Then I sent the request with this Axios JS code:

 onLogin( credentials ) {
    axios.post(
            Config.appUrl + 'oauth/token', {
            headers: {
                'accept': 'application/json',
                'accept-language': 'en_US',
                'content-type': 'application/x-www-form-urlencoded'
            }, auth: {
                username: Config.clientId,
                password: Config.clientSecret
            }, body: {
                'password': credentials.password,
                'username': credentials.username,
                'grant_type': 'password',
                'scope': 'read write',
                'client_secret': Config.clientSecret,
                'client_id': Config.clientId
            }
        }, Config )

The server responds with an error : "provider.endpoint.TokenEndpoint : Handling error: InvalidRequestException, Missing grant type".
From this, it sounds like the body is not being properly submitted (hence deciding to look at the headers and payload on the server).
Here is what we see on the server:

=== MimeHeaders ===
host = localhost:8081
user-agent = Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
accept = application/json, text/plain, /
accept-language = en-US,en;q=0.5
accept-encoding = gzip, deflate
content-type = application/json;charset=utf-8
referer = http://localhost:8081/merchant/
content-length = 321
cookie = JSESSIONID=69AA1724151AAE81659FDEC49354AA85
authorization = Basic d2VidWk6d2VidWlzZWNyZXQ=
connection = keep-alive

The requested Basic Auth does seem to be successfully applied with Axios.
However:

  • Headers are not honoured (content-type, for example, should be application/x-www-form-urlencoded, not application/json;charset=utf-8)
  • Content seems to be of completely different length

[AXIOS - FIELD NAMES]
And, I get the same result if I use the field name equivalents for the headers{accept} and body {*} segments:

 onLogin( credentials ) {
    axios.post(
        Config.appUrl + 'oauth/token', {
            headers: {
                accept: 'application/json',
                'accept-language': 'en_US',
                'content-type': 'application/x-www-form-urlencoded'
            }, auth: {
                username: Config.clientId,
                password: Config.clientSecret
            }, body: {
                password: credentials.password,
                username: credentials.username,
                grant_type: 'password',
                scope: 'read write',
                client_secret: Config.clientSecret,
                client_id: Config.clientId
            }
        }, Config )

Results in:

=== MimeHeaders ===
host = localhost:8081
user-agent = Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
accept = application/json, text/plain, /
accept-language = en-US,en;q=0.5
accept-encoding = gzip, deflate
content-type = application/json;charset=utf-8
referer = http://localhost:8081/merchant/
content-length = 321
cookie = JSESSIONID=69AA1724151AAE81659FDEC49354AA85
authorization = Basic d2VidWk6d2VidWlzZWNyZXQ=
connection = keep-alive

Here is my package.json content:

"devDependencies": {
"babel-core": "^6.21.0",
"babel-loader": "^6.2.10",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"eslint": "^3.13.1",
"eslint-config-airbnb": "^14.0.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^3.0.2",
"eslint-plugin-react": "^6.9.0",
"file-loader": "^0.9.0",
"react-hot-loader": "^1.3.1",
"react-router": "^3.0.2",
"webpack": "^1.14.0",
"webpack-dev-server": "^1.16.2"
},
"dependencies": {
"alt": "^0.17.4",
"axios": "^0.7.0",
"history": "^1.12.5",
"jsuri": "^1.3.1",
"rest": "^1.3.1",
"react-mixin": "^3.0.1",
"react": "^15.4.2",
"react-dom": "^15.4.2"
}

Can somebody please help me to identify what is wrong with my .post() request ?

@rubennorte
Copy link
Member

You aren't configuring the request correctly. The body option doesn't exist in axios. You should use data instead. And the first option for post is the data itself, not the axios config.

You can see an example request with content type application/x-www-form-urlencoded in the README: https://github.com/mzabriskie/axios#using-applicationx-www-form-urlencoded-format

@BenAhlander
Copy link

SignIn = () => {
    console.log('login clicked')
    let data = JSON.stringify({
        password: this.state.password,
        username: this.state.email
    })

    axios.post('url', data, {
        headers: {
            'Content-Type': 'application/json',
        }
    }
    )
}

@thiagosanches
Copy link

thiagosanches commented Oct 25, 2017

Hi guys, I opened a ticket that I believe that it might be related to this issue. #1149
Thank you.

@devaKumaraswamy
Copy link

I discovered that for this particular scenario (calling oauth/token endpoint) axios seems to be case sensitive for the content-type header key. 'Content-Type' works fine but 'content-type' results in a missing grant-type. I am running 0.18.0. Right now I am slammed with work - otherwise I would step into the debugger to see what is going on. Maybe the folks who are very knowledgeable with the internals of axios can either confirm or reject my statement.

I do want to state that I use axios extensively in my work - kudos the the author.

@quantuminformation
Copy link

I am using axios like so:

 axios
      .post(`${serviceRoot}/sendMail`, data)
      .then(function(response) {
        console.log(response)
        resolve(response)
      })

but there is no payload:

Screenshot 2019-06-01 at 12 21 36

The service works fine when posting with postman like tool:

Screenshot 2019-06-01 at 12 23 21

@alyatwa
Copy link

alyatwa commented Sep 20, 2019

It looks like you only have two points left to make it work :

one : the http method should be set to POST instead of GET since you want to send something.

two : you can then add the http header (like what you did with the authorization header) Content-Type: 'application/json`

On the back-end don't forget to use some kind of body parser utility package like this one : body-parser and set it up with your app.

I suppose your server is using express, here is how you will do it with express :

const express = require('express');
const app = express();
const bodyParser = require('body-parser')
const jsonParser = bodyParser.json();

app.use(jsonParser); // use it globally
app.get('your_route', jsonParser, otherMiddleware, (req, res) => ...); // use it for specific routes

/* ... rest of your code */

@axios axios locked and limited conversation to collaborators May 22, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants