3

I want to send JSON data (in this case is client timestamp) to my server. However, my code seem doesn't work as I expect.

My idea is using fetch to send FormData (which contain an input has JSON as value) to the PHP. At the server side, PHP will take care the form with $_POST and return JSON string to me.

I'm using a free host service, which has PHP 7.0, for testing stuff.

All of the code below is in the same file (404.php):

var now = new Date();

var pkg = JSON.stringify({
    ts: now.getTime(),
    tz: now.getTimezoneOffset() / -60
})

var form = new FormData();
form.set('json', pkg);

console.log(form.has('json')) // true
console.log(form.values().next()) // return and obj contain JSON string

fetch('/404.php', {
    method: 'POST',
    body: form
});
$json = null;
if(isset($_POST['json'])) $json = json_decode($_POST['json']);

var_dump($_POST); //Result: array(0) { }

As you can see, the output of var_dump is an empty array. But what I expect to see is an output with a JSON string.

I've tried another way, which is this one fetch-api-json-php, but it also no use. All the resource I found on the Internet usually about the classic AJAX, not fetch API. And most of them are only for client side, there isn't much I could find for PHP/server side.

  • What does $_POST on the PHP side contain? Have you var_dump'd the content of $_POST? – heiglandreas Apr 22 '19 at 05:58
  • Yes, it returns empty array. –  Apr 22 '19 at 06:22
  • Sorry. you posted that. So it's not PHP side but JS side. I assume that you need to send `form.values()`instead of `form` inside your `fetch()`. To be sure that the right data is sent check in the network tab in your developer console that the right data is transfered to the script. If nothing is sent in the body of the request PHP has nothung to work with – heiglandreas Apr 22 '19 at 06:30
  • You could also simplify things and replace `body: form.values()` with `body : {"json" : PKG} ` and skip all the form business. – heiglandreas Apr 22 '19 at 06:38
  • I don't think so, the fetch code I use is the common one on the Internet. But of course, everything's worth to try. However, nothing changes... –  Apr 22 '19 at 06:39
  • So what does your browser actually send? – heiglandreas Apr 22 '19 at 06:40
  • ‍♂️ IIRC `form` is a reserved name in the global scope. Rename the variable for a test and see what happens. – heiglandreas Apr 22 '19 at 06:42
  • How do I track it? The network tab of Firefox doesn't do the job –  Apr 22 '19 at 06:42
  • You JS file located in the same folder where PHP file for the post request? Becuase I ran your code in my localhost, I just change the POST request URl in fetch() method and its working just fine. – Vasant Hun Apr 22 '19 at 06:44
  • I've just changed from `form` to `formx` but it still doesn't work. I also try to test on Chrome but it's got the same result. –  Apr 22 '19 at 06:45
  • The network tab of firefox devtools contains all requests that are sent. Unless you have set a filter. See f. e. https://developer.mozilla.org/en-US/docs/Tools/Network_Monitor – heiglandreas Apr 22 '19 at 06:45
  • All of the code about are in the same file which is `404.php`. And I run this file on and actual host, not local one. (I don't know if I should add the link to here, I don't really believe in free host so it might look like spam) –  Apr 22 '19 at 06:49
  • @heiglandreas Do you think this could be server's fault? A [screenshot](https://imgur.com/ugKSPiF) that I capture from Chrome tab tells it get `error 500` why sending data. –  Apr 22 '19 at 07:06
  • when I interpret your screenshot from the Chrome DevTools (not Firefox DevTools) correctly you are sending the complete string as POST parameter to the script. That is a) not valid JSON and b) not valid POST-data as it's not key/value pairs. But as you already got a working answer that's fine. – heiglandreas Apr 22 '19 at 07:22

3 Answers3

0

This worked for me:

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<script>
    var pkg = '{"test":"data"}';
    var formData = new FormData();
    formData.set('json', pkg);

    fetch('./404.php', {
      method: 'POST',
      body: formData
    });
</script>
</head>
<body>

</body>
</html>

PHP:

<?php
$json = null;
if(isset($_POST['json'])) 
    $json = json_decode($_POST['json']);

var_dump($_POST, $json); 

// Result: array(1) { ["json"]=> string(15) "{"test":"data"}" } object(stdClass)#1 (1) { ["test"]=> string(4) "data" } 

?>
Kevin HR
  • 249
  • 1
  • 6
  • It doesn't work for me. Even if I set `pkg` a pure string value like you do. It still return a `null` value for `$json`. –  Apr 22 '19 at 06:27
0

Can you try to run this code in your local machine?

Make a file name 55788817.php and paste this code and run.

  <?php
  if (isset($_POST) && !empty($_POST)) {
    $json = null;
    if(isset($_POST['json'])) $json = json_decode($_POST['json']);

    var_dump($_POST); //Result: array(1) { ["json"]=> string(29) "{"ts":1555915560755,"tz":5.5}" }
    exit;
  }
  ?>
  <!DOCTYPE html>
  <html>
  <head>
    <title></title>
  </head>
  <body>
    <button type="button" id="registerButton">Click Me!</button>
    <script>
      var now = new Date();

      var pkg = JSON.stringify({
          ts: now.getTime(),
          tz: now.getTimezoneOffset() / -60
      })

      var form = new FormData();
      form.append('json', pkg);

      console.log(form.has('json')) // true
      console.log(form.values().next()) // return and obj contain JSON string
      fetch('./55788817.php', {
          method: 'POST',
          body: form
      });
    </script>
  </body>
  </html>
Vasant Hun
  • 61
  • 4
  • Do I have to run it on local host? Because I'm not using my pc (borrowing one, in fact) so I can not set up a localhost. But I has added your script to my shared-host and tried. What should I expect after click the button because it doesn't seem like return anything. –  Apr 22 '19 at 06:56
  • Check in Chrome > inspect > network tab and see the response for the above file. – Vasant Hun Apr 22 '19 at 06:57
  • Here is the result: [screenshot](https://imgur.com/ugKSPiF). I'm getting start to think this is the server's fault. –  Apr 22 '19 at 07:04
  • Hmm, have you check the request URL in fetch method? is correct path? If you think my answer help please mark this answer as Useful, thanks. – Vasant Hun Apr 22 '19 at 07:07
  • it's on the same file so it can be wrong url. Ok, will mark this answer for now. –  Apr 22 '19 at 07:12
0

Here a generic way to achieve this

HTML

<form name="myform" action="serverScriptOrFile.json" method="post">
    <input name="xxx"/>
</form>

Javascript

document.querySelector("form[name='myform']")?.addEventListener('submit', (e) => {
    e.preventDefault()
    fetch(e.target.action, {
        method: e.target.method,
        body: new FormData(e.target)
    })
    .then(response => response.json())
    .then(json => {
        console.log(json)
    })
})
user2752173
  • 470
  • 1
  • 6
  • 10