Estoy intentando enviar un documento JSON a un script PHP usando AJAX. El documento JSON se construye a partir del valor de un <textarea> .
Ejecuté con éxito la solución usando JQuery y (¿por diversión?) Estoy trabajando para lograr el mismo resultado con Vanilla AJAX.
El script PHP de llamada:
<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>El PHP receptor:
$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);Recibo el siguiente error y no puedo averiguar por qué no se recibe postData.html.
Warning: Undefined array key "html" in /Library/WebServer/Documents/markuppreview.php on line 8 {"success":false,"output":""} También probé un método de objeto Javascript para construir el documento JSON, pero recibí el mismo mensaje. Cuando alert al documento JSON, muestra un elemento html con los datos del <textarea> .
var postData = new Object(); postData.html = document.getElementById("editor").value; postData = JSON.stringify(postData); alert(postData);Hay múltiples problemas que se unen aquí:
Parece que intenta enviar JSON (de acuerdo con su Content-Type: application/json ), pero PHP de forma nativa solo admite datos de formulario (cadena de consulta o varias partes). Si desea usar JSON, debe acceder al cuerpo sin formato con file_get_contents('php://input') y usar json_decode para obtener un objeto (en lugar de usar la matriz asociativa superglobal $_POST ).
En realidad, no envía nada útil, porque está pasando un objeto a XMLHttpRequest#send que será forzado a una cadena y terminará como solo [object Object] . Si desea enviar JSON, primero deberá aplicar JSON.stringify en los datos y enviar el resultado.
A partir de aquí, puede cambiar tanto el cliente como el servidor para usar JSON por completo o actualizar el cliente para enviar datos de formulario.
Sin embargo, recomendaría cambiar a una solución más moderna (y fácil de usar) que XMLHttpRequest de todos modos, idealmente fetch . Con el código de servidor existente (usando datos de formulario), el siguiente código de cliente funcionaría:
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() } Si tiene la intención de mostrar solo la propiedad de output del objeto JSON que devuelve de su servidor y solo si el success es verdadero, entonces deberá usar esto en lugar de la línea await response.text() anterior:
const { success, output } = await response.json() if (success) document.getElementById('output').innerHTML = outputPorque está intentando enviar datos con formato JSON y $_POST funciona con datos de formulario, no con una carga JSON.
tendrás que hacer
$json = json_decode(file_get_contents('php://input'));para leer la entrada POST como una cadena sin procesar, luego JSON la decodifica.
Además, utilice fetch() en lugar de la API XMLHTTPRequest (bastante heredada).
Solución final según las sugerencias de @CherryDT.
Llamando script PHP:
<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>Recibir 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);