Axios posting params not read by $_POST

65,599

Solution 1

From the documentation (I haven't preserved links in the quoted material):

Using application/x-www-form-urlencoded format

By default, axios serializes JavaScript objects to JSON.

PHP doesn't support JSON as a data format for populating $_POST.

It only supports the machine-processable formats natively supported by HTML forms:

  • application/x-www-form-urlencoded
  • multipart/form-data

To send data in the application/x-www-form-urlencoded format instead, you can use one of the following options.

Browser

In a browser, you can use the URLSearchParams API as follows:

var params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params); 

Note that URLSearchParams is not supported by all browsers, but there is a polyfill available (make sure to polyfill the global environment).

Alternatively, you can encode data using the qs library:

var qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));

Or you could customise your PHP so it can handle JSON as per this answer on another question.

Solution 2

var params = {
    data1: 'string',
}

axios.post(url, params).then(function(response) {
    //code here 
});

or

axios.post(url, {data1: 'string' }).then(function(response) {
    //code here 
});

api

$_POST = json_decode(file_get_contents("php://input"),true);
echo $_POST['data1'];

Solution 3

To make things easier and universal if you ever decided to switch between AJAX libraries or server languages. With axios use the native JS FormData.
If you have your data in an object, you can convert it to FormData like this:

var myDataObj = {id:1, name:"blah blah"}
var formData = new FormData();


for (var key in myDataObj) {
    formData.append(key, myDataObj[key])
}

Then you send the data:

axios.post('/sub/process.php', formData, {
    params: { action: "update-user" },
    headers: { 'Content-Type': 'multipart/form-data' },
    baseURL: 'http://localhost',
}).then(data =>
    console.log(data)
).catch(err => {
    console.log(err)
    return null
})

Notice, you can also send some info using params in axios that you can retrieve using $_GET. Also notice that I am using the baseURL in case you have different servers for the web page and your API endpoint.
You need to understand also that before axios send the real request, it performs a preflight request. A preflight request, is a mechanism in CORS by the browser to check if the resource destination is willing to accept the real request or not. Afterall, why would a request be sent when the target host is not willing to receive it anyway?

You have to make sure that your server has the right headers for your axios request, otherwise the preflight request will detect the incompatibility and stop your request:

//this is if you are using different different origins/servers in your localhost, * to be update with the right address when it comes to production
header('Access-Control-Allow-Origin: *');
//this is if you are specifying content-type in your axios request
header("Access-Control-Allow-Headers: Content-Type");

Now, you will able to access your sent data in the $_POST variable:

echo "<pre>";
print_r($_POST);
echo "</pre>";

Additionally, axios allows you to send data in different formats. you can send a json for example like this:

axios.post('/sub/process.php', { id: "1", name:"blablah" }, {
    params: { action: "update-item" },
    headers: { 'Content-Type': 'application/json' },
    baseURL: 'http://localhost',
}).then(data =>
    console.log(data)
).catch(err => {
    console.log(err)
    return null
})

In the PHP side, this can be accessed as follows:

$data = json_decode(file_get_contents("php://input"),true);
echo "<pre>";
print_r($data);
echo "</pre>";

Solution 4

Using PHP std object

Using PHP std object structure to get the variables of the post.

On the client:

axios.post(url, {id: 1 , Name:'My Name' }).then(function(response) {
    console.log(response.data);
});

On the server

$obj = json_decode(file_get_contents('php://input'));   
$id = $obj->id;
$Name = $obj->Name;    

//test by returning the same values
$retObj=(object)["id"=>$id,"Name"=>$Name]
echo json_encode($retObj);

Both jQuery and Axios using same PHP file

if you have a file receiving post both from axios and jquery you may use:

if($_SERVER['REQUEST_METHOD']==='POST' && empty($_POST)) {
   $_POST = json_decode(file_get_contents('php://input'),true); 
}

to convert the Axios json-serialized posts to the $_POST array

Solution 5

This code works on browser/node both today. I think this is more practical. I tested this code on node.js and passed the data variable to PHP8 using $_POST['param1'] and it worked perfectly.

function axqs(d){
    let p = new URLSearchParams();
    Object.keys(d).forEach(function(key){
        p.append(key, this[key]);
    }, d);
    return p
}

let data = {
  'param1': 'value1',
  'param2': 'value2',
}

let p = axqs(data)
axios.post('/foo', p)
Share:
65,599
A. L
Author by

A. L

Updated on November 12, 2021

Comments

  • A. L
    A. L over 2 years

    So I have this code:

    axios({
        method: 'post',
        url,
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        data: {
            json,
            type,
        }   
    })  
    

    Originally I had the normal axios.post but I changed to this because I thought it might have been a header problem. However I am still detecting nothing in my $_REQUEST nor $_POST. However, it is receiving data in file_get_contents("php://input").

    Any idea what is wrong?

    Edit

    Okay I think I know what's wrong. It's posting it as a json object so it can only be read in the php://input. How do I change it to a normal string in axios?

  • A. L
    A. L about 7 years
    I'll try it if I ever use axios again, but I just switched to jQuery's ajax instead lol
  • Beniamin H
    Beniamin H over 4 years
    Hello @Russell Moore to SO. Actually there are already good answers to this question and your answer is not giving a clear explanation. Moreover you should not post your logins/passwords in any public website, even if it's only for your development environment.
  • Simon
    Simon almost 3 years
    may-2021 and still a simple and effective solution!
  • NeoTechni
    NeoTechni about 2 years
    There's no way to get axiom to do it properly? I don't want to have to put code on every page, when axiom is doing it wrong.
  • Palantir
    Palantir about 2 years
    For me it worked with var params = new FormData(); instead of URLSearchParams().
  • Quentin
    Quentin about 2 years
    @Palantir — That sends multipart data not URL encoded data (which the question was attempting to send)