Home > Software design >  How to send data along with a request in ajax
How to send data along with a request in ajax

Time:05-19

So, i am pretty new to ajax and i was working with a small project in which i need to make a query from a HTML form, but for some reason i can't send any data. I've tried to send a FormData through the xmlhttprequest.send() method, as well as an array containing values, but the php to which i'm sending the request gets absolutely nothing. Here's the html document

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>ajax</title>
    <script type="text/javascript">
        function pasarXMLATabla(xml){
            var empleados = xml.getElementsByTagName('empleado');
            var tabla = "<table> <tr> <th>ID</th> <th>Nombres</th> <th>Apellidos</th> <th>Salario</th> </tr>";
            for (var i = 0; i < empleados.length; i  ) {
                tabla  = "<tr> <td>" empleados[i].getElementsByTagName("id")[0].innerHTML "</td>";
                tabla  = "<td>" empleados[i].getElementsByTagName("nombre")[0].innerHTML "</td>";
                tabla  = "<td>" empleados[i].getElementsByTagName("apellidos")[0].innerHTML "</td>";
                tabla  = "<td>" empleados[i].getElementsByTagName("salario")[0].innerHTML "</td></tr>"; 
            }
            tabla  = "</table>"
            document.getElementById('lista-empleados').innerHTML=tabla;
        }
        function manejadorDeFormulario(){
            var datosDelFormulario = new FormData(document.getElementById('formulario'));
            const xhttp = new XMLHttpRequest();
            xhttp.onload = function () {
                var respuesta = xhttp.responseXML;
                pasarXMLATabla(respuesta);
                console.log(respuesta.getElementsByTagName('mensaje'));
            }
            xhttp.open("GET","empleados.php");
            xhttp.send(datosDelFormulario);
        }
    </script>
</head>
<body style="background-color:#9EADAD;">
    <form onsubmit="manejadorDeFormulario();return false;" id='formulario' method='get'>
        <select id='tipo-de-busqueda' name='tipo-de-busqueda'>
            <option value=''>--Seleccione el tipo de búsqueda a realizar--</option>
            <option value='1'>Salarios menores</option>
            <option value='2'>Salarios iguales</option>
            <option value='3'>Salarios mayores</option>
        </select>
        <input type="text" id='cantidad-de-salario'><br>
        <button type="submit">Realizar búsqueda</button>
    </form>
    <div id="lista-empleados"></div>
</body>
</html>

Here's the php

<?php
require_once("db/query_fns.php");
$empleadosEncontrados = buscarEmpleadosPorSalario();
require_once("views/empleadosxml.php");
function buscarEmpleadosPorSalario(){  
  $tipoDeBusqueda = $_GET['tipo-de-busqueda'];
  $cantidadDeSalario = $_GET['cantidad-de-salario'];
  $result = "";
  switch ($tipoDeBusqueda) {
    case 1:
      $sql = "SELECT * FROM empleados WHERE salario < " . $cantidadDeSalario;
      $result = getElements($sql);
      return $result;
      break;
    
    case 2:
      $sql = "SELECT * FROM empleados WHERE salario = " . $cantidadDeSalario;
      $result = getElements($sql);
      return $result;
      break;

    case 3:
      $sql = "SELECT * FROM empleados WHERE salario > " . $cantidadDeSalario;
      $result = getElements($sql);
      return $result;
      break;
  }
}
?>

The /views/empleadosxml.php document is where i build an XML from the results of the query, i've tested it giving specific values to $tipoDeBusqueda and $cantidadDeSalario and there's no errors there UNLESS i try to use $_GET. And the /db/query_fns document it's where i make the queries, and since i can generate the xml answer without a problem, then i can safely assume it's working. I have tried to store the $_GET values and then echo print_r them inside a new XML tag to see what am i getting in the $_GET, and it's always an empty array, regardless of if i'm using wether POST or GET. All my testing leads me to the $_GET being empty, since neither the query, XML generation or parsing, connection to server and database has problems, there's only problems when i don't give fixed values to $cantidadDeSalario and $tipoDeBusqueda, and the error i get is "extra content at the end of document". I have been trying all of this in OperaGX and Microsoft Edge with the same results. I can't use jquery for this.

CodePudding user response:

FormData is more suited to POST (and PUT, PATCH) requests, not GET. The reason is that FormData constructs a request body which includes the request data. But in a GET request, even if a body is specified, the server will might ignore it, the browser might ignore it, or either might thrown an error (thanks to @Phil for corrections in the comments).

The FormData docs describe this but perhaps don't make it explicitly clear (emphasis mine):

The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the fetch() or XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to "multipart/form-data".

The key there is the last sentence; multipart/form-data is only for requests with a body, like POST.

The next sentence of the same docs clarify a little bit about what to do for GET:

You can also pass it directly to the URLSearchParams constructor if you want to generate query parameters in the way a <form> would do if it were using simple GET submission.

The URLSearchParams docs show we can use it to set up the query string that is the right way to send data in a GET request; they even suggest we can use FormData to simplify constructing that string. And a bit of searching turns up a neat example of how to do that:

var parameters = new URLSearchParams(new FormData(myForm)).toString()

Then we just need to append that query string to your base URL.

There's one other problem in your code - FormData will only work for inputs that have names. Your text input does not, so it will never appear in FormData, nor the query string, nor show up in $_GET on the back end. Add a name to the input to solve that.

Here's a simplified version of your code with these changes and fixes applied. Click Run, and open your browser devtools console, and watch the Network tab. Select an option, add some text, and click submit. You'll see a 404 of course (empleados.php doesn't exist here on SO) but you'll also see the query string appended to the requested URL, and on your server those values will be available in $_GET. On your server where the PHP exists it will work fine.

function manejadorDeFormulario(){
    var datosDelFormulario = new FormData(document.getElementById('formulario'));
    var parameters = new URLSearchParams(datosDelFormulario).toString();
    
    const xhttp = new XMLHttpRequest();
    xhttp.open("GET", "empleados.php?"   parameters);
    xhttp.send(datosDelFormulario);
}
<form onsubmit="manejadorDeFormulario();return false;" id='formulario' method='get'>
    <select id='tipo-de-busqueda' name='tipo-de-busqueda'>
        <option value=''>--Seleccione el tipo de búsqueda a realizar--</option>
        <option value='1'>Salarios menores</option>
        <option value='2'>Salarios iguales</option>
        <option value='3'>Salarios mayores</option>
    </select>
    <input type="text" id='cantidad-de-salario' name="text"><br>
    <button type="submit">Realizar búsqueda</button>
</form>

CodePudding user response:

As I understand it you can't send data with a GET request. If you're sending something with the request you'd have to do something like this:


function manejadorDeFormulario(){
    var selectValue = document.querySelector("#tipo-de-busqueda").value,
        inplutValue = document.querySelector("#cantidad-de-salario").value;

    const xhttp = new XMLHttpRequest();
    xhttp.onload = function () {
        var respuesta = xhttp.responseXML;
        pasarXMLATabla(respuesta);
        console.log(respuesta.getElementsByTagName('mensaje'));
    }

    xhttp.open("GET",`empleados.php?tipo-de-busqueda=${encodeURIComponent(selectValue)}&cantidad-de-salario=${encodeURIComponent(inplutValue)}`);
    xhttp.send();
}

So above you're opening a request and sending a value to the PHP file that the $_GET superglobal can access.

Then in the PHP you'd do something like this:


<?php
require_once("db/query_fns.php");

if (isset($_GET["tipo-de-busqueda"])) {
    $empleadosEncontrados = buscarEmpleadosPorSalario($_GET);
}

require_once("views/empleadosxml.php");

function buscarEmpleadosPorSalario($request){  
  $tipoDeBusqueda = $request['tipo-de-busqueda'];
  $cantidadDeSalario = $request['cantidad-de-salario'];
  $result = "";

  switch ($tipoDeBusqueda) {
    case 1:
      $sql = "SELECT * FROM empleados WHERE salario < " . $cantidadDeSalario;
      $result = getElements($sql);
      break;
    
    case 2:
      $sql = "SELECT * FROM empleados WHERE salario = " . $cantidadDeSalario;
      $result = getElements($sql);
      break;

    case 3:
      $sql = "SELECT * FROM empleados WHERE salario > " . $cantidadDeSalario;
      $result = getElements($sql);
      break;
  }

  echo $result;
}

You want to make sure the GET request is targeting the correct function so that a response can be returned. So I wrapped the $_GET in an isset function and passed the $_GET params to the function.

I hope my answer helps, I can't really test your code I can only really offer up suggestions to the best of my ability by just reading it. If you want more clarification feel free to ask. (:

  • Related