【问题标题】:Proper way to send JSON in XMLHttpRequest in WordPress without jQuery.ajax在没有 jQuery.ajax 的 WordPress 中以 XMLHttpRequest 发送 JSON 的正确方法
【发布时间】:2019-08-04 03:55:23
【问题描述】:

我正在尝试在 WordPress 中使用 XMLHttpRequest 发送 JSON 数据:

document.getElementById("user_vote").addEventListener("click", function(event) {
    event.preventDefault();

    //action to handle in WP add_action("wp_ajax_my_user_vote", "my_user_vote");
    let action = "my_user_vote";
    let url = myAjax.ajaxurl;

    let data = {
        action: action,
        post_id : this.dataset.post_id,
        nonce: this.dataset.nonce
    };

    let json = JSON.stringify(data);

    let xhr = new XMLHttpRequest();

    xhr.open("POST", url, true);
    xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');

    xhr.onreadystatechange = function() {
        if (this.readyState != 4) return;

        document.getElementById('response').innerHTML = this.responseText;
    }

    xhr.send(json);
});

当我将标头设置为 JSON xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8'); 时,$_REQUEST 变量为空。似乎 WP 不理解这个标题或者我做错了什么。

我看到了这个post。当我在admin-ajax.php 中检查$input = file_get_contents('php://input'); 时,它返回我的数据字符串:{"action":"my_user_vote","post_id":"1","nonce":"2b2eaea6d3"}$_REQUEST 变量为空。

使用此标头 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 一切正常,但我想发送 JSON。

为什么使用 jQuery.ajax 我可以简单地将 JSON 数据发送到 admin-ajax.php 而不能使用 javascript?

加1

以下是在 WP 中发送 AJAX 的正确方法:

jQuery.ajax({
    type : "post",
    dataType : "json",
    url : myAjax.ajaxurl,
    data : {action: "my_user_vote", post_id : post_id, nonce: nonce},
    success: function(response) {
        //do stuff
    }
})

您的意思是,在这种情况下,jQuery 不会将标头设置为application/json,而是将它们设置为application/x-www-form-urlencoded,并且所有这些请求都将生成为带有标准标头的简单XMLHttpRequest,并将xhr.send(data) 转换为字符串,一些东西像这样"action=my_user_vote&post_id=1&nonce=2b2eaea6d3"

而且我不需要将标头设置为 application/json 并使用带有标准标头的简单 POST 请求?

【问题讨论】:

  • 如果您将 jQuery ajax data 属性设置为像您这样的对象,jQuery 会将其转换为普通表单参数。
  • @Pointy OP 不想使用 ajax。此外,从内容类型标头中删除“charset=utf-8”,它不应该包含在其中。
  • @garryman — OP 询问为什么 jQuery 和 XHR 似乎有不同的行为。该评论完全相关。
  • @garryman — 在 charset 标头中包含 charset 参数没有任何问题。

标签: javascript json wordpress xmlhttprequest


【解决方案1】:

PHP 不会自动解码 JSON 并将其放入 $_POST$_REQUEST

正如您已经发现的,您需要从 STDIN 读取原始 HTTP 请求正文并显式解析它以在 PHP 中读取 JSON 格式的请求。


您的问题似乎是对 jQuery 功能的误解。可能当您使用 jQuery 时,您正在做这样的事情:

var data = { some: "object" };
jQuery.ajax({
    url: "foo",
    data: data,
    method: "POST"
});

当你这样做时,jQuery 将对data 对象进行 URL 编码。它不会对其进行 JSON 编码。

请记住,虽然 JSON 语法受到 JavaScript 文字语法的启发,但在 JavaScript 源代码中包含对象文字的结果会给您一个对象,而不是 JSON 字符串。

如果您使用 jQuery 发出 JSON 格式的请求,您需要这样的东西:

jQuery.ajax({
    url: "foo",
    data: JSON.stringify(data),
    contentType: "application/json; charset=utf-8",
    method: "POST"
});

要使用 XHR 将您的对象编码为表单数据,您需要以下内容:

var data = { some: "object" };
var array = [];
Object.keys(data).forEach(element => 
    array.push( 
        encodeURIComponent(element) + "=" + encodeURIComponent(data[element])
    )
);
var body = array.join("&");
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(body);

【讨论】:

  • 请在我的问题中检查 Add 1
  • @Alexander — 这似乎是在重复我在回答中已经说过的话。
  • 我是在您编辑答案时写的 :) 谢谢!感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 2021-11-22
  • 1970-01-01
  • 2019-10-09
相关资源
最近更新 更多