Axios: Unable to POST data in axios

Created on 21 Nov 2017  ·  62Comments  ·  Source: axios/axios

I am using this code to POST the data to Web API
var param = {
args: {
myStringVal: '979251e4-6c9f-460d-ba32-1b6fe58ce8a3'
}
};

axios({
method: 'post',
url: 'api/Application/Action/MyWebAPIMethod',
data: JSON.stringify(param),
});

and my Web API code is like this:
public class MyClassVM
{
public string myStringVal { get; set; }
}
public MessageVM MyWebAPIMethod(MyClassVM args){
// my code goes here
}

Issue is: When I pass the myStringVal: '979251e4-6c9f-460d-ba32-1b6fe58ce8a3' it gives me null in Web API [args.myStringVal = null ].

How can I pass the values in axios POST.

Thanks in advance

Most helpful comment

I've recently started moving from using jQuery for AJAX work to Axios, just because it seems to be all the rage. But I was shocked to learn I can't do a simple POST.

So, here's what I first tried:

axios.post('/api/event/item', {
    event_id: eventId,
    item_id: itemId,
    description: description
  })
  .catch(function (error) {
    console.log(error);
  });

On the backend (using PHP) $_POST was completely empty. So I did some googling, and this works (with the use of a polyfill, sigh):

const params = new URLSearchParams();
params.append('event_id', eventId);
params.append('item_id', itemId);
params.append('description', description);
axios({
  method: 'post',
  url: '/api/event/item',
  data: params
});

This works. So I need to use URLSearchParams? Well this was frustrating because the docs show that the first method should work.

Anyone else having this trouble?

All 62 comments

@awais-ilyas , I don't think you would normally stringify the POST payload. Try this:

...
axios({
method: 'post',
url: 'api/Application/Action/MyWebAPIMethod',
data: args,
});
...

Which should set the data in the POST body.

I've recently started moving from using jQuery for AJAX work to Axios, just because it seems to be all the rage. But I was shocked to learn I can't do a simple POST.

So, here's what I first tried:

axios.post('/api/event/item', {
    event_id: eventId,
    item_id: itemId,
    description: description
  })
  .catch(function (error) {
    console.log(error);
  });

On the backend (using PHP) $_POST was completely empty. So I did some googling, and this works (with the use of a polyfill, sigh):

const params = new URLSearchParams();
params.append('event_id', eventId);
params.append('item_id', itemId);
params.append('description', description);
axios({
  method: 'post',
  url: '/api/event/item',
  data: params
});

This works. So I need to use URLSearchParams? Well this was frustrating because the docs show that the first method should work.

Anyone else having this trouble?

@dlgoodchild Are you trying to send it as Form data? I found my POST body was empty too, but I had to use this to transform it into something Form-like:

   ...
      data: params,
      transformRequest: [
        function(data, headers) {
          const serializedData = []

          for (const k in data) {
            if (data[k]) {
              serializedData.push(`${k}=${encodeURIComponent(data[k])}`)
            }
          }

          return serializedData.join('&')
        }
      ],
   ...

Agreed, the POST functionality needs work.

Ahh good approach! For the benefits of anyone landing here, in the end I got it working using in 3 variants:

  1. FormData
  2. URLSearchParams
  3. querystring.stringify (part of Node)

The problem with the first 2 options is browser compatibility (check with caniuse.com). The last is another depdendency.

I wasn't aware of the transformRequest option, this looks good and is a great option if you want minimise dependencies and work cross browser particularly for older versions.

I think the documentation is what makes Axios frustrating for many people. The number of StackOverflow questions relating to POST using Axios is a good indication there's a problem somewhere and general misunderstanding.

Have the same problem - spent few hours on research, finally found this issue. Thoughts: POST shouldn't be complicated, and shouldn't require dependencies or extra configuration. This feels like AngularJS 1 all over again. I'll pass on using this library for now.

@yuri-wisestamp couldn't agree more, it's a very odd/unusal design choice. I've mostly stopped using it now as I felt spurned by the hours I lost debugging it due to lack of good documentation to lay this out from the outset.

Post with Axios and PHP is a true nightmare !

I spent two hours, without getting any result...

Non-form-encoded posts do not populate $_POST in PHP. You have to read the post body:

$body = file_get_contents('php://input');

if you expect json:

$json=json_decode($body);

This code:

axios = require('axios');

var param = {
   args: {
      myStringVal: '979251e4-6c9f-460d-ba32-1b6fe58ce8a3'
   }
};

axios({
   method: 'post',
   url: 'http://home.test/post.php',
   data: param,
});

Against this in the server:

<?php

$entityBody = file_get_contents('php://input');

file_put_contents(__DIR__ . '/output.txt', print_r(json_decode($entityBody), true));

Produced this output:

stdClass Object
(
    [args] => stdClass Object
        (
            [myStringVal] => 979251e4-6c9f-460d-ba32-1b6fe58ce8a3
        )

)

I fixed my issue like that :

Front

✋userSearchParams() doesn't work everywhere ( https://caniuse.com/#search=URLSearchParams() )

        let params = new URLSearchParams();
        params.append('email', this.email );
        params.append('url', userInfo.url );
        this.$http.post(
          'http://localhost:9999/api/record.php', params
          )
        .then((response) => {
          if (response.data.message === "success" )  this.$router.push( 'thankyou' );
        })
        .catch( (error) =>   console.log(error) ) ;

Back

print_r( $_POST ); 

// $_POST['email'] = '[email protected]'
// $_POST['url'] = 'http://google.fr'

I got mine to work by installing qs.

          import qs from "qs";


        const params = {
            name: "User",
            startTime: "2:00PM",
            endTime: "3:00PM",
            status: "pending",
            invitation: "test",
        };

        axios.post("DOMAIN/event/new", qs.stringify(params))
            .then((response) => {
                console.log(response);
            })
            .catch((error) => {
                console.log(error);
            });

@Legym Thanks! I got mine working as well with qs.stringify! Damn I was about to stop using axios since I could not get my POST requests to work correctly!

Many thanks!

I actually found a better solution without the need for an external library. The Post request Header is set to form. You'll need to change the header if you are sending a JSON object

        const params = {
            name: "User",
            startTime: "2:00PM",
            endTime: "3:00PM",
            status: "pending",
            invitation: "test",
        };

axios.post('DOMAIN/event/new', params, {
     headers: {
          'content-type': 'application/json',
     },
})

@Legym Thank you very much!

I really don't understand why POST doesn't work. Legym's headers don't fix it for me.
jquery worked first try so i dont know what's going on.

The URLSearchParams approach doesn't work for Safari in macOS.

Has anyone been able to POST a file and data via axios?
I'm using PHP's Laravel framework.

@latanoil honestly, there's little to no upside to using axios. Best to stick to a simpler, better supported, better documented Ajax library. Jquery is tried and tested and works perfectly well and you'll have none of the issues found here.

Thanks @dlgoodchild for the advice. I have struggled with this for a couple of days now. I'll just stick to jQuery.

axios({
  method: 'post',
  url: 'http://blahblahblah',
  params: {
    key1: value1,
    key2: value2
  }
})

work this way, use _params_, not _data_

LOL I cannot believe this was so hard to get working.

Something _this_ basic, _this_ ... _common_, should NOT be hard.

@HellsingMatt nope didn't work for me. It's possible you have that confused with $_GET. Because 'params' is what I used to get it working for GET. But it did not work for me with POST.

@mallochine interesting, I do use _params_ with POST in node.js

@HellsingMatt ok. I'm using PHP. It looks like axios completely craps up with PHP. Are you using PHP backend?

@mallochine never learnt PHP yet, all my backend using node.js

I'm using PHP. No issues.
In some cases I want json (usually), so I set the header accordingly. In cases where I want $_POST populated I use a library like qs or my own smaller simpler implementation (which wouldn't handle all cases but is adequate for me) to convert to a query string.

See this SO post for an example on one such function: https://stackoverflow.com/a/1714899/6728516

This quirk of Axios has been addressed in the main documentation for a long time, though admittedly it could be a bit more descriptive.

I generally find using JSON so much more versatile that I rarely do this any longer. See my comment above for a method for retrieving the posted JSON in PHP.

Bloody hell.

I didnt want to break standard api functionality for forms, so had to add fallback .

if(empty($_POST['dep_date'])) {
    $body = file_get_contents('php://input');
    $json = json_decode($body, true);
    $_POST['dep_date'] = $json['dep_date'];
    .....

Luckily I had access to php side, if it would be some external api i would be §§§ . There should be warning about this when listing all ajax clients for vue :)

It work with me using "params", and I use PHP with this.
Note that this is axios inside nativescript-vue 2.0.0.

@HellsingMatt Thank you!

I got mine to work by installing qs.

          import qs from "qs";


        const params = {
            name: "User",
            startTime: "2:00PM",
            endTime: "3:00PM",
            status: "pending",
            invitation: "test",
        };

        axios.post("DOMAIN/event/new", qs.stringify(params))
            .then((response) => {
                console.log(response);
            })
            .catch((error) => {
                console.log(error);
            });

P

Please can you post the php backend code with all cors headers and content type. I have tried both axios and fetch both are not working.

It's seems like mistake in documentation, but should use params object, no data and it's working. I've spent 2 hours to understand it((

axios({
  method: 'post',
  url: 'url',
  params: {
    key: value
  }
})

Thanks alot Daniil. I appreciate your help. Thanks for letting me know the
error.

On Sat, Nov 10, 2018 at 11:18 AM Daniil notifications@github.com wrote:

It's seems like mistake in documentation, but should use params object, no
data and it's working. I've spent 2 hours to understand it((

axios({
method: 'post',
url: '/wp-admin/admin-ajax.php?action=data_fetch',
params: {
key: value
}
})


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/axios/axios/issues/1195#issuecomment-437612819, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ApIWeUP45k17b70vsaT80KR1g_cxXcMvks5utyZzgaJpZM4Ql8j5
.

I fixed my issue like that :

Front

✋userSearchParams() doesn't work everywhere ( https://caniuse.com/#search=URLSearchParams() )

        let params = new URLSearchParams();
        params.append('email', this.email );
        params.append('url', userInfo.url );
        this.$http.post(
          'http://localhost:9999/api/record.php', params
          )
        .then((response) => {
          if (response.data.message === "success" )  this.$router.push( 'thankyou' );
        })
        .catch( (error) =>   console.log(error) ) ;

Back

print_r( $_POST ); 

// $_POST['email'] = '[email protected]'
// $_POST['url'] = 'http://google.fr'

It help so much, thank you!

axios({
  method: 'post',
  url: 'http://blahblahblah',
  params: {
    key1: value1,
    key2: value2
  }
})

work this way, use _params_, not _data_

works for me too thanks, much cleaner approach.

I have an Axios instance already created with the base url.

I want to make a post using that instance. What's the correct setup?

This works:

    axios({
        method: "post",
        url: "https://slack.com/api/chat.postMessage",
        params: {
            token: this.token,
            channel: this.channel,
            text: "Testing API"
        },
        transformRequest: [
            (data, headers) => {
                console.log("data-in-transform", data);
                delete headers.post["Content-Type"];
                return data;
            }
        ]
    });

This does not work:

    ax = axios.create({
        baseURL: `https://slack.com/api/`,
        params: {
            token: this.token,
            channel: this.channel
        },
        withCredentials: false,
        transformRequest: [
            (data, headers) => {
                delete headers.post["Content-Type"];
                return data;
            }
        ]
    });
        this.ax.post("chat.postMessage", {
            withCredentials: false,
            params: {
                text: "Testing API"
            },
            transformRequest: [
                (data, headers) => {
                    console.log("data-in-transform", data);
                    delete headers.post["Content-Type"];
                    return data;
                }
            ]
        });

I spent 15 days to solve this issue :( Here is the Code

 Axios({

        method: apiMethod,
        url: root_url, // Api URL
        data: (apiMethod === 'POST')? Qs.stringify(apiParams) : undefined, // API post parameters,
        params:(apiMethod === 'get')? apiParams : undefined, //API get params
        headers:{
          'Accept': 'application/json',
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        },

    }).then(function (response) { // On Success
        console.log('Response', response.data );

        successCallback(response.status, response.data);
    })
    .catch(function (error) { // On Failure
        console.log('error', error);

        errorCallback(error.status, error.data);
    })
    .then(function () { // Always
        alwaysCallback(false);
    });

That's simply horrible. Such a long discussion for just sending a POST request and at the end we have no concrete solution yet.

I am facing the same issue and already spent 3 days. Tried all combinations and options possible and still finding myself at the same situation. Hence my backend is also written in PHP, I too feel that axios has major issues with POST and PHP combination, which is simply unaccepted!!

jQuery handles these things exceptionally well and I am going to switch back to it again. I don't want to install additional dependencies just for sending a POST request!

Also, the thread is closed without a proper solution!!

It was closed by @awais-ilyas, he should ideally reopen it, if that's possible.

Yeah! But the thread does not take me anywhere. Sending a POST request to PHP using JSON object is still been a pain! @dlgoodchild is there any workaround yet since I am a late comer to this thread?

yeah @emfluenceindia there are plenty of workarounds mentioned in this thread that don't require using JSON.

I saw them. Does this mean it is still not possible to POST as JSON?

This thread isn't really about posting JSON. Posting JSON as a post body isn't an issue, this thread is about using the data: attribute, like with jQuery and having that somehow populate $_POST in PHP.

I've recently started moving from using jQuery for AJAX work to Axios, just because it seems to be all the rage. But I was shocked to learn I can't do a simple POST.

So, here's what I first tried:

axios.post('/api/event/item', {
    event_id: eventId,
    item_id: itemId,
    description: description
  })
  .catch(function (error) {
    console.log(error);
  });

On the backend (using PHP) $_POST was completely empty. So I did some googling, and this works (with the use of a polyfill, sigh):

const params = new URLSearchParams();
params.append('event_id', eventId);
params.append('item_id', itemId);
params.append('description', description);
axios({
  method: 'post',
  url: '/api/event/item',
  data: params
});

This works. So I need to use URLSearchParams? Well this was frustrating because the docs show that the first method should work.

Anyone else having this trouble?

I met this problem today and i have spent nearly a whole day on this. its weird because the document of axios told me to use first method which didnt work. thank u, bro

did you guys put
app.use(express.json())
at the app.js?

This should be enough:

const formData = new FormData();
formData.append('action', 'some-action');
formData.append('page', 1);

axios
  .post('/async/index.php', formData, {
    retry: 3,
    retryDelay: 100,
  })
  .then(res => {
    console.log('get', res.data);
  })
  .catch(console.log);

PHP

print_r($_POST);

The answer is to add the following. Axios uses url-form-encoded by default.

headers: {
  "Content-Type": "text/plain"
}

None of these solutions worked for me, and I think it's because for node.js users the README is misleading because you _must have a data object_ for post requests because the config object is the _3rd argument_ passed in. The .post function has this interface

post(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise;

so you must call the .post function like this

await axios.post(
 `http://localhost:3000/your/path/here`,
 {},
 {
   params: {
     ID: 12345,
     name: 'testUser',
   },
 },
);

@NathanielRN this solution works but it's not optimal. It appends all the parameters to the url. Similar to the "get".

@NathanielRN this solution works but it's not optimal. It appends all the parameters to the url. Similar to the "get".

@nicolardi Sorry I'm not too familiar with url request performance. While is adding the parameters to the url not optimal? Even if it is like a "get"?

Axios is the most famous client around yet it has such a flaw. Disappointing.

Reopening for investigation

Here is the thing: the problem isn't with Axios. If you use cURL or Postman with the same parameters (method: Post, Body: {"something":"value"}, headers set to json) it works. However, if you do it using Axios or even Fetch API in your Vue, React, Angular (whatever) you'll see your Chrome or (any other browser) "changing" the Request Method (see the Network tab) to OPTIONS and NOT POST anymore. The reason behind it is... CORS (Cross-origin resource sharing). I found it out because I'm making my API using NestJS and I forgot to enable CORS. When enabled, the Request Method is keeped as POST (as we wished) and Axios will be able to return your JSON (or any other format). Some frameworks set the CORS automatically (e.g. Laravel) where others you must set/enable it manually.

This should be enough:

const formData = new FormData();
formData.append('action', 'some-action');
formData.append('page', 1);

axios
  .post('/async/index.php', formData, {
    retry: 3,
    retryDelay: 100,
  })
  .then(res => {
    console.log('get', res.data);
  })
  .catch(console.log);

PHP

print_r($_POST);

solution by @jonataswalker is the best approach to handle POST using Axios. Using FormData() worked for me.

so i have kind of the same problome. i am using Vue.js for my front and i found out the since i did the update to the last version (axios , and vue) i can not send the data in any way. in my last project i could send data in any of the format.

In older versions working fine and in the updated not working at all.

axios.post('/actions/posts/create_questionnaire' , { questionnaire : form })

my advise if the post does not work try to use a older version of axios and the freamwork you are using.

I ran into this problem with a django backend. Fortunately I have a workaround using GET but axios.post definitely doesn't work as documented.

It might be that it's not axios problem but cors.
If you are posting from node server to php backend then your php script needs to have cors:

https://stackoverflow.com/a/55392661

and also not use $_POST but $data = file_get_contents('php://input');

This seems to be working to retrieve the $_POST value in PHP:

    axios.post(url, {test: 'dafasfasfa'},{
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            "Access-Control-Allow-Origin": "*"
        }
    })

I finally got this working with a django backend (with cors installed and configured) like this, using a combination of @alvarotrigo 's and @latanoel's ideas:

const formData = new FormData();
formData.append('a1', this.form.a1);
formData.append('a2', this.form.a2);
formData.append('a3', this.form.a3);

axios
  .post(url, formData, {
    headers: {
      'Content-type': 'application/x-www-form-urlencoded',
    }
  })
etc

When you include the POST args inline as the docs suggest, POST is empty in the backend. Also, you cannot set Access-Control-Allow-Origin because that violates cors.

Also, cam across this method too
const paramsCompose = (formData) => { const str = []; for (let p in formData) { str.push(encodeURIComponent(p) + '=' + encodeURIComponent(formData[p])); } const body = str.join('&'); console.log('PARAMS ' + body); return body; };

Then you ...
return axios.post(url, paramsCompose({ image_url: image_url, cover_name: cover_name })) .then(res => { const tx = res.data; console.log(tx); return res.data });

After few days and trying all the previous options... I still have no success on solve the problem.

What we have, in fact is:

  • The Axios 'post' method doesn't work as documented;
  • Execute a simple 'post' call to a REST service became a hell, using Axios;

I just can't believe it's serious... sorry but I'll be back to use another API. Goodbye Axios.

@fabriciobraga I was trying to figure out why this was happening in my application as well. I spent the entire day scouring the Internet for the solution. However, I found out that it was a very simple issue. My user create action looked like this at first:

createUser(context, user) {
    this.$axios.$post("/api/users/", user).then(response => {
      context.dispatch("fetchUsers");
    });
 }

The user parameter there is an object containing the email and password of the new user. I tried to console.log the user object and it reported that the properties were undefined! 🤔

Screen Shot 2020-01-27 at 10 00 04 PM

So I spread the user object when passing it to the $post method and now it works!

 this.$axios.$post("/api/users/", {...user})

In my case, the user object was being sent as empty object and my API reported it be so. If you're facing the same problem maybe you should try this.

One other possible scenario is that your data is being sent just fine but not in the format that your API is expecting (e.g. a common format for PHP scripts is form-data while most Node.js APIs expect JSON). So you need to figure this out; see the discussions above.

Having the same problem apparently
axios.post("api", { API: 1, version: "0.1b"...})....
Results with empty API and version when reaching my Java rest server.
When sending it as the 3rd paramter, ie
axios.post("api", null, { params: {API: 1, version: "0.1b"...}})....
It works as expected

This is one of the most commented and opened issue. Believe me that I have read every comment in this thread. Lots of users got confused how to post data by axios. Someone gave their hits or conclusions and new users missed their directions again.

Remember that axios is only a request client. If you didn't see the expected response, check whether things that axios sends match what the server expects. Here are my main steps to solve post or even all axios problems. And I also hope users can open issue with following questions answered. Maybe update the issue template later.

  1. Which side did you run your codes? The browser or the server side.
  2. What parameters do you want to send? Should use config.params or config.data?
  3. If params, how to encode them? Is the default config.paramsSerializer enough or should use a customized?
  4. If data, did you encode them with the correct content-type header? Most post problems failed here.

    1. The header application/json requires JSON.stringify and the header application/x-www-form-urlencoded requires qs.stringify.

    2. The default config.transformRequest will set application/x-www-form-urlencoded for URLSearchParams, and application/json for Javascript objects. Please check sources codes in lib/defaults.js to get accurate understandings.

  5. Did you meet other problems, i.e. CORS/ATS/Promises, and know how to solve them?

I know they looks like complex and I am planing to write a tutorial explains as detailed as possible. But I am not a native speaker and a little worried about my article level. Forgive me to lock it and please wait for my or someone from the community to give a well-written document. This is open source. We need everyone's contribution.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jdpagley picture jdpagley  ·  3Comments

ghost picture ghost  ·  3Comments

emaincourt picture emaincourt  ·  3Comments

altruisticsoftware picture altruisticsoftware  ·  3Comments

Spartano picture Spartano  ·  3Comments