0

I am using jQuery to submit the following request:

$.ajax({
    url: encodeURI('/server/api/user/update.php/'),
    method: 'POST',
    contentType: 'application/json',
    headers: {
        'Authorization': 'Bearer ' + utility.getJsonWebToken()
    },
    data: JSON.stringify(e.model),
    dataType: 'json'
})

And I have the following PHP code that verifies that the request is valid and contains the necessary body:

// check for bad method
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    $returnedJson['error'] = 'The supplied request method is not supported for the requested resource. This resource expects a POST request.';
    echo json_encode($returnedJson);
    return;
}

// check for bad request
$errors = array();
$user = new UserModel();
foreach (UserModel::$RequiredColumnNames as $property) {
    $success = ControllerUtility::isValueInRequest($_POST, $property);
    if (!$success) {
        array_push($errors, $property);
        continue;
    }
    $user->$property = $_POST[$property];
}
if (count($errors) > 0) {
    http_response_code(400);
    $returnedJson['error'] = 'Malformed request syntax. The following properties are missing from the request: ' . join(', ', $errors);
    echo json_encode($returnedJson);
    return;
}

Every time I submit the request, I get 400 error with the 'Malformed request syntax. The following properties are missing from the request: ...' error message.

I echoed the $_POST and $_REQUEST but in both instances and empty array is returned.

I verified that the request headers is a POST:

POST /server/api/user/update.php/ HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Authorization: Bearer -removed-
X-Requested-With: XMLHttpRequest
Content-Length: 180
Origin: http://localhost
Connection: keep-alive
Referer: -removed-
Sec-GPC: 1

And the fields are included in my request JSON:

{
    "CreatedBy": null,
    "CreatedOn": "2021-02-28 13:53:54",
    "DeletedOn": null,
    "Email": "-removed-",
    "ModifiedBy": "1",
    "ModifiedOn": "2021-02-28 16:35:51",
    "UserId": "1",
    "Username": "Adminn"
}

I have even removed the content-type header from my PHP without success. I've also tried just passing e.model instead of calling stringify in the AJAX request. At this point I'm at a loss as to what I'm doing wrong.

David
  • 5,877
  • 3
  • 23
  • 40
  • 1
    See https://stackoverflow.com/a/11990821/14066311 – Prince Dorcis Mar 01 '21 at 00:38
  • 1
    Why do you have a slash after `update.php`? – John Conde Mar 01 '21 at 00:38
  • Side note: there's no need to `encodeURI()`. – kmoser Mar 01 '21 at 00:42
  • 1
    First, you can't just `echo $_POST` and `$_REQUEST` since they are arrays. Try `var_dump($_REQUEST)` instead. Second, you wrote _"And the fields are included in my request JSON:"_ but you did not show how you verified that. Are you doing a `console.log(e.model)`? Where exactly are you doing that? – kmoser Mar 01 '21 at 00:46
  • 1
    What does the `ControllerUtility::isValueInRequest` function do? We can't see the code for that, but that seems to be the place where it checks whether your values are there or not. Seem pretty critical to the question really... – ADyson Mar 01 '21 at 00:49
  • ...however, from the arguments you passed into it, I see it seems to rely on checking $_POST. But you're sending JSON, so that isn't going to work. Please read this: [Receive JSON Post with PHP](https://stackoverflow.com/questions/18866571/receive-json-post-with-php) – ADyson Mar 01 '21 at 00:50
  • Yep, like ADyson's comment, you need to check what's going on in here that keeps pushing errors to the $errors list: $success = ControllerUtility::isValueInRequest($_POST, $property); – Christian Hur Mar 01 '21 at 00:56
  • @ChristianHur if you look at the link in my second comment, it becomes obvious what's going on, even without seeing the code. – ADyson Mar 01 '21 at 00:57
  • @PrinceDorcis - Yes, that does thank you. – David Mar 01 '21 at 01:06
  • @JohnConde - So that it shows the entire URL in my network tab. – David Mar 01 '21 at 01:10
  • @kmoser - Correct, while it is not needed in this instance I try to include on every request because some requests I pass a query string. Also, I didn't "just echo $_POST" I didn't include the code for brevity but I called `echo json_encode($_POST)` and `echo json_encode($_REQUEST)`. Finally, I did explain how you verified that my JSON is included in my request, I pulled it from the network tab. – David Mar 01 '21 at 01:10
  • @ADyson - the isValueInRequest does: `return is_array($request) && array_key_exists($key, $request) && !is_null($request[$key]);`. – David Mar 01 '21 at 01:10
  • Ok. Well when you send JSON data correctly, the input isn't in $_POST at all. Read the link I gave above. – ADyson Mar 01 '21 at 01:12
  • 1
    @ADyson - There were a bunch of comments above the one directed to you, but it looks the link that Prince Dorcis provided is the solution, which is basically the same thing that you linked to. – David Mar 01 '21 at 01:13

1 Answers1

-3

// echo the json string from php://input.

file_get_contents('php://input');
Chester
  • 722
  • 4
  • 6
  • 3
    You're on the right lines but this is a very lazy answer. And it's not quite correct either. Format the code, correct it, and write an explanation. Might as well close the question as a duplicate of https://stackoverflow.com/questions/18866571/receive-json-post-with-php if that's the best we can do. https://stackoverflow.com/help/how-to-answer – ADyson Mar 01 '21 at 01:06