Правильный способ отправить JSON в XMLHttpRequest в WordPress без jQuery.ajax - PullRequest
0 голосов
/ 13 марта 2019

Я пытаюсь отправить данные JSON с помощью XMLHttpRequest в WordPress:

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 не понимает эти заголовки, или я делаю что-то не так.

Я видел этот пост . Когда я проверяю $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

Вот правильный способ отправки AJAX в WP:

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 запрос со стандартными заголовками?

1 Ответ

2 голосов
/ 13 марта 2019

PHP не будет автоматически декодировать JSON и помещать его в $_POST или $_REQUEST.

Как вы уже обнаружили, вам нужно прочитать необработанное тело HTTP-запроса из STDIN и разобрать его явно, чтобы прочитать запрос в формате JSON в PHP.


Ваша проблема заключается в неправильном понимании того, что делает jQuery. Вероятно, когда вы используете jQuery, вы делаете что-то вроде этого:

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

Когда вы сделаете это, jQuery будет URL кодировать объект data. Он будет не 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...