简体   繁体   English

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

[英]AJAX: How to send a simple parameter by POST in vanilla JS

In jQuery, the code is like this, and everything is happy as a lark:在jQuery中,代码是这样的,万事如意:

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

The console in Firefox's dev tools says that "Form data" contains empty=1 , and the PHP file gets what it wants. Firefox 开发工具中的控制台显示“表单数据”包含empty=1 ,并且 PHP 文件得到它想要的。 I don't really understand that syntax (what { } does and while empty isn't in quotes), but it works.我不太了解这种语法( { }做了什么,而empty不在引号中),但它确实有效。

Now I need to do the same thing in plain Javascript.现在我需要在普通的 Javascript 中做同样的事情。 Here is my code:这是我的代码:

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

For the parameter of xhr.send() I have tried the following, none of which work:对于 xhr.send() 的参数,我尝试了以下方法,但均无效:

  • 'empty=1' (according to this answer ): The console says it's in "Request payload", not "Form data". 'empty=1' (根据这个答案):控制台说它在“请求有效负载”中,而不是“表单数据”中。
  • {empty:"1"} or {"empty":"1"} : The console says "Request payload" contains "[object Object]". {empty:"1"}{"empty":"1"} :控制台说“请求有效负载”包含“[object Object]”。
  • '{"empty":"1"}' : The console says it's in a section called "JSON". '{"empty":"1"}' :控制台说它在一个名为“JSON”的部分中。

This would be easy with GET, but since it is changing something on the server, POST is more proper.使用 GET 这很容易,但由于它正在更改服务器上的某些内容,因此 POST 更合适。 What is the right syntax?什么是正确的语法?


EDIT in response to Rayon and Atul Sharma:编辑以回应 Rayon 和 Atul Sharma:

Hmm, something else fundamental must be wrong.嗯,其他基本的东西一定是错的。 For diagnostics, I currently have this as the first line in bucket.php:对于诊断,我目前将此作为 bucket.php 中的第一行:

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

Whether I use xhr.send(JSON.stringify({empty: '1'})) (Atul Sharma's answer) or xhr.send('{"empty":"1"}') (Rayon's comment), I get the result shown in this screenshot of the console and the output from the server:无论我使用xhr.send(JSON.stringify({empty: '1'})) (Atul Sharma 的回答)还是xhr.send('{"empty":"1"}') (Rayon 的评论),我都会得到结果显示在控制台截图和来自服务器的 output 中: 在此处输入图像描述

And I decided to test GET - I changed the open command to this:我决定测试 GET - 我将 open 命令更改为:

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

The console says Query String contains empty: "1" , but on the server $_GET and $_POST are still empty?控制台说 Query String contains empty: "1" ,但在服务器上$_GET$_POST仍然是空的? Does vanilla JS just hate me. vanilla JS只是讨厌我吗。 This works fine in jQuery.这在 jQuery 中运行良好。


EDIT #2: It's just me (or my server)!编辑#2:这只是我(或我的服务器)!

After discovering that even my original simplest syntax works on jsfiddle ( https://jsfiddle.net/3j42ztpf/ ), I wrote a WME test file pair for my own server.在发现即使我最初最简单的语法也适用于 jsfiddle ( https://jsfiddle.net/3j42ztpf/ ) 后,我为自己的服务器编写了一个 WME 测试文件对。 On both my local VM and my production VPS, it acts the same way - jQuery works but plain JS doesn't, regardless of whether the parameter is sent as text or JSON.在我的本地 VM 和生产 VPS 上,它的行为方式相同 - jQuery 有效,但普通 JS 无效,无论参数是以文本形式还是 JSON 发送。 There must be something different in the HTTP request between the JSFiddle test and the first link on my server test, but I can't spot it in devtools - the Request Payload is identical and the differences in the headers all seem logical.在 JSFiddle 测试和我的服务器测试上的第一个链接之间的 HTTP 请求中一定有一些不同,但我无法在 devtools 中发现它 - 请求有效负载是相同的,并且标头中的差异似乎都是合乎逻辑的。 Try it yourself at: https://dev.kizunadb.com/testajax.html亲自尝试: https://dev.kizunadb.com/testajax.html

The back-end file testajax.php only contains this:后端文件 testajax.php 只包含这个:

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

So I really do have a more fundamental problem than just bad syntax.所以我确实有一个比糟糕的语法更根本的问题。 Can anyone spot the issue in their dev tools, or suggest something I should check on my server?任何人都可以在他们的开发工具中发现这个问题,或者建议我应该在我的服务器上检查一些东西吗?

While researching suggestions in the comments from @StackSlave and @Rayon, I learned more about Content-Type.在研究 @StackSlave 和 @Rayon 的评论中的建议时,我了解了更多关于 Content-Type 的信息。 It turns out that all I needed was to set the Content-Type to "application/x-www-form-urlencoded".事实证明,我需要的只是将 Content-Type 设置为“application/x-www-form-urlencoded”。 All three people who tried to help (one of whom removed their answer later) focused on passing data back and forth as JSON, but that's really unnecessary in this case and just makes the code harder to read (in my opinion anyway).所有三个试图提供帮助的人(其中一个人后来删除了他们的答案)都专注于将数据作为 JSON 来回传递,但在这种情况下这真的没有必要,只会让代码更难阅读(无论如何我认为)。 So here is the final version of the function, the main point being the last two lines (I also had to change how I was writing the returned number into the DOM - getElementsByClassName returns an HTMLCollection that must be handled correctly):所以这是 function 的最终版本,重点是最后两行(我还必须更改将返回的数字写入 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');
}

Particularly helpful SO answers and other pages were:特别有用的 SO 答案和其他页面是:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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