Khor Shuqi

PHP: Reading JSON from Javascript Fetch API and Axios

If you tried to send a POST request by following tutorials of the new Fetch API in Vanilla JS, or if you use Axios, which sends form data in JSON format by default, you might be surprised that $_POST is empty, the entire JSON data is missing.

This is because PHP only reads the form data in url-encoded format:

PHP
URL ENCODED FORMAT:
category=5&page=2&sort=price

JSON FORMAT:
{"category":5,"page":2,"sort":"price"}

What we could do, is to manually read the JSON data from php://input, and decode it with json_decode():

PHP
<?php

$php_input = file_get_contents("php://input");
$data = json_decode($php_input, true);
if ($data) {
  // decode successful
}

But not all data sent via POST are in JSON format, so instead of firing up json_decode() every time, we should first check the content type and see whether it is a JSON:

PHP
<?php

if (!empty($_SERVER['CONTENT_TYPE']) && preg_match("/application\/json/i", $_SERVER['CONTENT_TYPE'])) {
  $php_input = file_get_contents("php://input");
  if ($data = json_decode($php_input, true)) {
    // decode successful
  }
}

Now, since that it is a POST request anyway, it is logical to map it into $_POST for use later:

PHP
<?php

if (!empty($_SERVER['CONTENT_TYPE']) && preg_match("/application\/json/i", $_SERVER['CONTENT_TYPE'])) {
  if ($php_input = json_decode(trim(file_get_contents("php://input")), true)) {
    $_POST = array_merge_recursive($_POST, $php_input);
  }
}

Finally, you could wrap it in a function if you like:

PHP
<?php

function accept_json_data () {
  if (!empty($_SERVER['CONTENT_TYPE']) && preg_match("/application\/json/i", $_SERVER['CONTENT_TYPE'])) {
    if ($php_input = json_decode(trim(file_get_contents("php://input")), true)) {
      $_POST = array_merge_recursive($_POST, $php_input);
    }
  }
}

accept_json_data();

Have fun!