AJAX:如何在 vanilla JS 中通过 POST 发送一个简单的参数

问题描述 投票:0回答:2

在jQuery中,代码是这样的,一切皆大欢喜:

$.post("bucket.php", { empty:"1" }, function(r) { ... });

Firefox 开发工具中的控制台显示“表单数据”包含

empty=1
,PHP 文件得到了它想要的内容。我真的不明白这种语法(
{ }
做什么,而
empty
不在引号中),但它有效。

现在我需要用纯 Javascript 做同样的事情。这是我的代码:

function bucketEmpty() {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if(xhr.readyState == 4 && xhr.status == 200) {  //no error
      if (!isNaN(xhr.responseText)) {  // return string is a number (expecting 0)
        document.getElementsByClassName('bucketcount').innerHTML = xhr.responseText;
      } else {
        alert(xhr.responseText);
      }
    }
  };
  xhr.open('POST', 'bucket.php');
  xhr.send(???what goes here???);
}

对于 xhr.send() 的参数,我尝试了以下方法,但都不起作用:

  • 'empty=1'
    (根据this answer):控制台说它在“请求有效负载”中,而不是“表单数据”中。
  • {empty:"1"}
    {"empty":"1"}
    :控制台显示“请求负载”包含“[对象对象]”。
  • '{"empty":"1"}'
    :控制台说它在一个名为“JSON”的部分中。

这对于 GET 来说很容易,但由于它正在更改服务器上的某些内容,因此 POST 更合适。什么是正确的语法?


编辑以回应 Rayon 和 Atul Sharma:

嗯,其他基本问题一定是错的。对于诊断,我目前将其作为 bucket.php 中的第一行:

die("GET:\n".print_r($_POST,true)."\nPOST:\n".print_r($_POST,true));

无论我使用

xhr.send(JSON.stringify({empty: '1'}))
(Atul Sharma 的回答)还是
xhr.send('{"empty":"1"}')
(Rayon 的评论),我都会得到控制台截图和服务器输出中显示的结果:

我决定测试 GET - 我将打开命令更改为:

xhr.open('GET', 'bucket.php?empty=1');

控制台说查询字符串包含

empty: "1"
,但是在服务器上
$_GET
$_POST
仍然是空的!香草 JS 只是讨厌我吗?这在 jQuery 中运行良好。


编辑#2:只有我(或我的服务器)!

在发现连我原来最简单的语法在jsfiddle(https://jsfiddle.net/3j42ztpf/)上都可以工作后,我为自己的服务器写了一个WME测试文件对。在我的本地 VM 和我的生产 VPS 上,它的行为方式相同 - jQuery 工作但普通 JS 不工作,无论参数是作为文本还是 JSON 发送。在 JSFiddle 测试和我的服务器测试的第一个链接之间的 HTTP 请求中肯定有一些不同,但我无法在 devtools 中发现它 - 请求有效负载是相同的,标头中的差异似乎都是合乎逻辑的。自己尝试:https://dev.kizunadb.com/testajax.html

后端文件testajax.php只有这个:

<?php
if (empty($_POST['text'])) {
  die('What do you want me to say?');
} else {
  die ($_POST['text']);
}

所以我确实有一个比糟糕的语法更根本的问题。任何人都可以在他们的开发工具中发现问题,或者建议我应该检查我的服务器吗?

javascript ajax post xmlhttprequest
2个回答
2
投票

在研究@StackSlave 和@Rayon 的评论中的建议时,我了解了更多有关 Content-Type 的知识。事实证明,我所需要的只是将 Content-Type 设置为“application/x-www-form-urlencoded”。所有三个试图提供帮助的人(其中一个人后来删除了他们的答案)都专注于以 JSON 格式来回传递数据,但在这种情况下这真的没有必要,只会让代码更难阅读(无论如何在我看来)。所以这是该函数的最终版本,重点是最后两行(我还必须更改将返回的数字写入 DOM 的方式 - getElementsByClassName 返回一个必须正确处理的 HTMLCollection):

function bucketEmpty() {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if(xhr.readyState === 4 && xhr.status === 200) {  //no error
      if (!isNaN(xhr.responseText)) {  // return string is a number (expecting 0)
        var elements = document.getElementsByClassName('bucketcount');
        [].forEach.call(elements, function (el) { el.innerHTML = xhr.responseText; });
      } else {
        alert(xhr.responseText);
      }
    }
  };
  xhr.open('POST', 'bucket.php');
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  xhr.send('empty=1');
}

特别有用的 SO 答案和其他页面是:


0
投票

xhr.send('empty=1');
这是否意味着 php 文件中的 $_POST['empty']?

© www.soinside.com 2019 - 2024. All rights reserved.