0

I'm using a PHP rest API to post data from JS client to a PHP 8 server. I'm using the JS fetch() method. When using POST the formdata is send to PHP's global $_POST, but since I need to update data I have to use PUT. Somehow Google Chrome is not sending the formdata to the server and I don't know why. Somebody knows the reason?

JS:

const formData = new FormData();
formData.append('title', 'Hello world');

const options = {
    method: 'PUT',
    body: JSON.stringify(formData);
    cache: 'no-cache',
    mode: 'cors',
    credentials: 'same-origin',
    redirect: 'follow',
    referrer: 'no-referrer',
    
    // Not working either
    // headers: {
    //     'Content-Type': 'application/json; charset=UTF-8;'
    // },
};

fetch('/some/api/v1', options);
PHP 8 server:

var_dump($_REQUEST); // NULL
2
  • 2
    You can't JSON.stringify FormData. Just send that as body. Browser knows how to serialize it. See Upload File example in MDN Using Fetch Commented Mar 28, 2021 at 0:21
  • 1
    Or for simple case like shown don't bother using FormData and send stringified plain object as JSON Commented Mar 28, 2021 at 0:27

1 Answer 1

1

The problem is not on the client but on the server. Both Firefox and Chrome serialize the data and send it with this code:

document.getElementById('myForm').addEventListener('submit', function(e){
            e.preventDefault();
            let fd = new FormData(this);
            fetch('test.php', {method:'PUT', body:fd})
            .then(function(response){
                response.text().then(function(txt){console.log("Response:"+txt);});
            });
        });

The problem is with PHP support for PUT, which doesn't automatically unpack the data for you. You can get it from the stdin stream.

/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
while ($data = fread($putdata, 1024)) {
    echo $data;
}

Response:

-----------------------------256278305409917102757952731 
Content-Disposition: form-data; 
name="myText" ffsssssdd 
-----------------------------256278305409917102757952731-- 

If you want to send your form data as a JSON object you can use this:

const serialize_form = form => JSON.stringify(
    Array.from(new FormData(form).entries())
        .reduce((m, [ key, value ]) => Object.assign(m, { [key]: value }), {})
        );
           
const json = serialize_form(this);
fetch('test.php', {method:'PUT', body:json, headers:{'content-type':'application/json'}})
    .then(function(response){
         response.text().then(function(txt){console.log("Response:"+txt);});
                });

Response:

{"myText":"ghfghfghfg"}

the serialize_form function taken from this answer

See the PHP reference

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your clear answer and code example! I didn't knew that PUT is not automatically unpacked by PHP. I was able to solve the issue, once again thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.