skip to Main Content

I’m having trouble posting data to an API using Fetch. I’ve simplified it to the following:

I created a simple PHP file at https://sophivorus.com/post.php with the following code:

<?php
echo json_encode( $_POST );

If I browse to it, open the dev console, and run the following simple command:

fetch( 'https://sophivorus.com/post.php', {
    method: 'POST',
} ).then( response => response.json() ).then( console.log );

I get a valid, empty JSON response. However, if I add a payload:

fetch( 'https://sophivorus.com/post.php', {
    method: 'POST',
    body: JSON.stringify( {
        foo: 'bar'
    } ),
} ).then( response => response.json() ).then( console.log );

I would expect to get a JSON response with the posted values. But I get the same, empty response. It seems that for some reason, my POST data is not getting posted.

I’m sure it must be something really stupid, but I just can’t see it. Any help would be most welcome, thanks!!

3

Answers


  1. Try to add 'Content-Type': 'application/json' in your fetch header options. It helps the server to interpret the data you are sending.

    fetch( 'https://sophivorus.com/post.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify( {
            foo: 'bar'
        } ),
    } ).then( response => response.json() ).then( console.log );
    

    Ref: Is Content-Type mandatory in HTTP post request?

    Login or Signup to reply.
  2. The problem is not related to fetch. A simple client request shows the same problem:

    > POST /post.php HTTP/2
    > Host: sophivorus.com
    > user-agent: insomnia/2023.3.0
    > content-type: application/json
    > accept: */*
    > content-length: 21
    
    * TLSv1.2 (OUT), TLS header, Supplemental data (23):
    
    | {
    |     "foo": "bar"
    | }
    
    * We are completely uploaded and fine
    * TLSv1.2 (IN), TLS header, Supplemental data (23):
    * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
    * TLSv1.2 (IN), TLS header, Supplemental data (23):
    * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
    * old SSL session ID is stale, removing
    * TLSv1.2 (IN), TLS header, Supplemental data (23):
    * TLSv1.2 (OUT), TLS header, Supplemental data (23):
    * TLSv1.2 (IN), TLS header, Supplemental data (23):
    
    < HTTP/2 200 
    < date: Sun, 24 Sep 2023 06:45:02 GMT
    < server: Apache
    < cache-control: max-age=600
    < expires: Sun, 24 Sep 2023 06:55:02 GMT
    < vary: User-Agent
    < content-length: 2
    < content-type: text/html; charset=UTF-8
    

    Response: []

    The $_POST array is for request body urlencoded parameters, not json.

    Try:

    <?php
    // Get the JSON contents
    $json = file_get_contents('php://input');
    
    // Return json data
    echo $json;
    
    
    To apply the json to an associative array:
    
    $entityData = json_decode($json, true);
    
    Now you can access foo as follows:
    
    $entityData['foo']
    
    Login or Signup to reply.
  3. Using FormData instead of JSON.stringify works. I am not very well versed with PHP, but my theory is that PHP doesn’t parse JSON data automatically (when using JSON.stringify). You need to use json_decode first, before echoing the json_encode. FormData on the other hand, is automatically parsed into $_POST array.

    let fd = new FormData()
    fd.append("foo", "bar")
    
    fetch( 'https://sophivorus.com/post.php', {
        method: 'POST',
        body: fd,
    } ).then( response => response.json() ).then( console.log );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search