I just ran into a problem and I wanted to document it for myself and for anyone else who might have issues. First I describe the problem, then I give the solution. Scroll down if you’re looking for the solution.
The Problem
After posting with JavaScript fetch I did not see the “body” arguments come through on the server. The method of the fetch was set to POST
and the body included was an instance of FormData
. According to the documentation on MDN, everything should’ve worked. So why wasn’t it working?
The Basic Client Side Code
const body = new FormData(myForm)
// assume myForm.action = "https://example.com/ajax/post"
const response = await fetch(myForm.action, {
method: "post",
body,
})
The Basic Server Side Code
<?php
// file: index.php within the ajax/post directory
// don't bother processing the post if there is none
if(empty($_POST)){
exit;
}
// ... processing code below
I spent some time debugging and without a doubt, every POST request to the index.php file did not have the $_POST
array filled out. The POST array was empty as well as the REQUEST array, even the oft-touted file_get_contents('php://input')
came up empty.
The Solution
You aren’t going to like it. I don’t like it. The solution to this problem is so annoying that you’ll just facepalm like Picard.
Add a slash to the end of the url you are posting to.
The problem url is: https://example.com/ajax/post
The working url is: https://example.com/ajax/post/
Currently, when this url is posted to, the server responds with a 301 Redirect before the index.php
file is hit. But why? The problem is that you do not have a trailing slash in your url. That’s it. You are posting to an index.php
file within a directory, but your url does not have a trailing slash. So your server helpfully redirects you to a url with a trailing slash, and you lose your posted information along the way.
Yep, that’s it. Add a trailing slash and you’ll see your body come through when debugging.