简体   繁体   中英

Send JSON document to PHP script using vanilla AJAX (not JQuery)

I'm attempting to send a JSON document to a PHP script using AJAX. The JSON document is constructed from the value of a <textarea> .

I have successfully executed the solution using JQuery, and (for fun?.) am working on achieving the same result with vanilla AJAX.

The calling PHP script:

<script>
  function preview() {
    var xhttp;
    xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("output").innerHTML = this.responseText;
      }
    };
    var postData = {
        'html' : document.getElementById("editor").value,
    };
    xhttp.open("POST", "markuppreview.php");
    xhttp.setRequestHeader('Content-type', 'application/json');
    xhttp.send(postData);
  };
</script>

<pre><textarea id="editor" name="content" placeholder="Enter your markup"></textarea></pre><br />
<button value="Preview" onclick="preview();">Preview</button>
<h2>Preview</h2>
<div id="output" style="height:100px"></div>

The receiving PHP:

$Parsedown = new Parsedown();
$Parsedown->setSafeMode(true);

$data['success'] = false;
$data['output'] = '';
if ($_POST['html']) {
    $data['success'] = true;
    $data['output'] = $Parsedown->text($_POST['html']);
}
echo json_encode($data);

I receive the following error, and can't work out why the postData.html isn't being received.

Warning: Undefined array key "html" in /Library/WebServer/Documents/markuppreview.php on line 8
{"success":false,"output":""}

I also tried a Javascript object method for constructing the JSON document, but received the same message. When I alert the JSON document, it does show an html element with the data from the <textarea> .

    var postData = new Object();
    postData.html = document.getElementById("editor").value;
    postData = JSON.stringify(postData);
    alert(postData);

Because you're attempting to send JSON-formatted data and $_POST works with form data, not a JSON payload.

You'll need to do

$json = json_decode(file_get_contents('php://input'));

to read the POST input as a raw string, then JSON decode it.

Also, please use fetch() instead of the (pretty legacy) XMLHTTPRequest API.

There are multiple problems coming together here:

  1. You seem to attempt to send JSON (according to your Content-Type: application/json header), yet PHP natively only supports form data. If you want to use JSON, then you have to access the raw body with file_get_contents('php://input') and use json_decode on it to get an object (instead of using the associative array superglobal $_POST ).

  2. You don't actually send anything useful, because you are passing an object to XMLHttpRequest#send which will get coerced to a string and end up as just [object Object] . If you do want to send JSON, you'll have to apply JSON.stringify on the data first and send the result.

Going from here, you can either change both client and server to fully use JSON or update the client to send form data.

However, I would recommend to switch to a more modern (and easy-to-use) solution than XMLHttpRequest anyway, ideally fetch . With the existing server code (using form data), the following client code would work:

async function preview () {
  const response = await fetch('markuppreview.php', {
    method: 'POST',
    body: new URLSearchParams({ html: document.getElementById("editor").value })
  })
  document.getElementById('output').innerHTML = await response.text()
}

Final solution as per @CherryDT's suggestions.

Calling PHP script:

<script>
async function preview () {
    const response = await fetch('markuppreview.php', {
          method: 'POST',
            'Accept': 'application/json',
            'Content-Type': 'application/x-www-form-urlencoded',
          body: new URLSearchParams({ html: document.getElementById("editor").value })
    })
    const { success, output } = await response.json()
    if (success) document.getElementById('output').innerHTML = output
}
</script>
<pre><textarea id="editor" name="content" placeholder="Enter your markup"></textarea></pre><br />
<button value="Preview" onclick="preview();">Preview</button>
<h2>Preview</h2>
<div id="output" style="height:100px"></div>

Receiving PHP:

$Parsedown = new Parsedown();
$Parsedown->setSafeMode(true);

$data['success'] = false;
$data['output'] = '';
if ($_POST['html']) {
    $data['success'] = true;
    $data['output'] = $Parsedown->text($_POST['html']);
}
echo json_encode($data);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM