Javascript 在WordPress中用XMLHttpRequest发送JSON而不使用jQuery.ajax的正确方法

Javascript 在WordPress中用XMLHttpRequest发送JSON而不使用jQuery.ajax的正确方法,javascript,json,wordpress,xmlhttprequest,Javascript,Json,Wordpress,Xmlhttprequest,我正在尝试使用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 =

我正在尝试使用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')我得到一个空的
$\u请求
变量。似乎WP不理解这个标题,或者我做错了什么

我看到了这个。当我检查
$input=file\u get\u contents('php://input');
admin ajax.php
中,它返回我的数据字符串:
{“操作”:“我的用户投票”,“发布id”:“1”,“nonce”:“2B2EAEAA6D3”}
$\u请求
变量为空

所有这些都可以很好地使用这些头
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\u user\u vote&post\u id=1&nonce=2b2aea6d3”


我不需要将标题设置为
application/json
,并使用标准标题的简单
POST
请求?

PHP不会自动解码json并将其放入
$\u POST
$\u请求中

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


您的问题似乎是对jQuery功能的误解。可能在使用jQuery时,您正在执行以下操作:

var data = { some: "object" };
jQuery.ajax({
    url: "foo",
    data: data,
    method: "POST"
});
jQuery.ajax({
    url: "foo",
    data: JSON.stringify(data),
    contentType: "application/json; charset=utf-8",
    method: "POST"
});
当您这样做时,jQuery将URL编码
数据
对象,而不是JSON编码

请记住,虽然JSON语法受JavaScript文本语法的启发,但在JavaScript源代码中使用对象文本的结果将为您提供一个对象,而不是一个JSON字符串

如果使用jQuery发出JSON格式的请求,则需要如下内容:

var data = { some: "object" };
jQuery.ajax({
    url: "foo",
    data: data,
    method: "POST"
});
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);

PHP不会自动解码JSON并将其放入
$\u POST
$\u请求中

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


您的问题似乎是对jQuery功能的误解。可能在使用jQuery时,您正在执行以下操作:

var data = { some: "object" };
jQuery.ajax({
    url: "foo",
    data: data,
    method: "POST"
});
jQuery.ajax({
    url: "foo",
    data: JSON.stringify(data),
    contentType: "application/json; charset=utf-8",
    method: "POST"
});
当您这样做时,jQuery将URL编码
数据
对象,而不是JSON编码

请记住,虽然JSON语法受JavaScript文本语法的启发,但在JavaScript源代码中使用对象文本的结果将为您提供一个对象,而不是一个JSON字符串

如果使用jQuery发出JSON格式的请求,则需要如下内容:

var data = { some: "object" };
jQuery.ajax({
    url: "foo",
    data: data,
    method: "POST"
});
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);

如果将jQuery ajax
data
属性设置为像您这样的对象,jQuery会将其转换为普通的表单参数。@Pointy OP不想使用ajax。另外,从内容类型头中删除“charset=utf-8”,它不应该包含在其中。@garryman-OP会问为什么jQuery和XHR看起来有不同的behaviours。注释完全相关。@garryman-在
内容类型
标题中包含
字符集
参数没有问题。如果您将jQuery ajax
数据
属性设置为与您类似的对象,jQuery会将其转换为普通形式参数。@Pointy OP不想使用ajax.Also、 从内容类型标题中删除“charset=utf-8”,它不应该包含在该标题中。@garryman-OP询问为什么jQuery和XHR看起来有不同的行为。注释是完全相关的。@garryman-在
内容类型
标题中包含
字符集
参数没有错在我的问题中加上1,please@Alexander-这似乎重复了我在回答中已经说过的话。我是在你编辑答案时写的:)谢谢!我感谢你的帮助。在我的问题中选择Add 1,please@Alexander-这似乎重复了我在回答中说过的话。我是在你编辑你的文章时写的回答:)谢谢你!我感谢你的帮助。