首页 > 解决方案 > 在没有 jQuery.ajax 的 WordPress 中以 XMLHttpRequest 发送 JSON 的正确方法

问题描述

我正在尝试在 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);
});

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

我看到了这个帖子。当我检查它$input = file_get_contents('php://input');admin-ajax.php返回我的数据字符串:{"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请求与标准标头一起使用?

标签: javascriptjsonwordpressxmlhttprequest

解决方案


PHP不会自动解码 JSON 并将其放入$_POSTor中$_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);

推荐阅读