如何在 ajax 中随请求一起发送数据

How to send data along with a request in ajax

所以,我是 ajax 的新手,我正在处理一个小项目,我需要从 HTML 表单进行查询,但由于某些原因我不能发送任何数据。我试图通过 xmlhttprequest.send() 方法发送一个 FormData,以及一个包含值的数组,但是我向其发送请求的 php 绝对没有任何结果。 这是 html 文档

<!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>

这是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;
  }
}
?>

/views/empleadosxml.php 文档是我根据查询结果构建 XML 的地方,我已经测试过它为 $tipoDeBusqueda 和 $cantidadDeSalario 提供了特定的值,并且那里没有错误,除非我尝试使用 $_GET。 /db/query_fns 文档是我进行查询的地方,因为我可以毫无问题地生成 xml 答案,所以我可以放心地假设它正在工作。我试图存储 $_GET 值,然后在新的 XML 标记中回显 print_r 它们以查看我在 $_GET 中得到了什么,它始终是一个空数组,无论我是否m 使用 wether POST 或 GET。我所有的测试都导致 $_GET 为空,因为查询、XML 生成或解析、与服务器和数据库的连接都没有问题,只有当我不为 $cantidadDeSalario 和 $ 提供固定值时才会出现问题tipoDeBusqueda,我得到的错误是“文档末尾的额外内容”。 我一直在 OperaGX 和 Microsoft Edge 中尝试所有这些,结果相同。 我不能为此使用 jquery。

据我了解,您无法使用 GET 请求发送数据。如果您要发送带有请求的内容,则必须执行以下操作:


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();
}

所以上面你打开了一个请求并向 $_GET 超全局变量可以访问的 PHP 文件发送了一个值。

然后在 PHP 你会做这样的事情:


<?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;
}

您要确保 GET 请求以正确的函数为目标,以便可以返回响应。所以我将 $_GET 包装在一个 isset 函数中并将 $_GET 参数传递给该函数。

希望我的回答对您有所帮助,我无法真正测试您的代码,我只能通过阅读它来提供我力所能及的建议。如果您想了解更多信息,请随时询问。 (:

FormData 更适合 POST(和 PUTPATCH)请求,而不是 GET。原因是 FormData 构造了一个包含请求数据的请求 body。但是在 GET 请求中,即使指定了主体,the server will might ignore it,浏览器也可能会忽略它,或者可能会抛出错误(感谢@Phil 在评论中的更正)。

The FormData docs 对此进行描述,但可能没有明确说明(强调我的):

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".

关键在最后一句; multipart/form-data 仅适用于带有正文的请求,例如 POST.

同一文档的下一句稍微阐明了为 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 表明我们可以使用它来设置查询字符串,这是在 GET 请求中发送数据的正确方式;他们甚至建议我们可以使用 FormData 来简化该字符串的构造。 搜索了一下 :

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

然后我们只需要将该查询字符串附加到您的基础 URL。

您的代码中还有一个问题 - FormData 仅适用于具有名称的输入。您的文本输入没有,因此它永远不会出现在 FormData 中,也不会出现在查询字符串中,也不会出现在后端的 $_GET 中。在输入中添加一个名称来解决这个问题。

这是应用了这些更改和修复的代码的简化版本。单击 运行,然后打开浏览器开发工具控制台,然后查看网络选项卡。 Select一个选项,添加一些文字,然后点击提交。您当然会看到 404(empleados.php 在 SO 上不存在),但您还会看到附加到请求的 URL 的查询字符串,并且在您的服务器上这些值将可用在 $_GET。在存在 PHP 的服务器上,它将正常工作。

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>