使用AJAX发出POST请求会返回400错误(不使用jQuery)

时间:2018-03-13 作者:James

该网站有一个带有搜索字段和类别复选框的博客页面。搜索某个内容或选中/取消选中某个类别会启动AJAX请求,以根据搜索/类别获取帖子,然后将这些结果填充到页面上的列表中。

Currently this functionality works with jQuery, but my attempts to write it in plain JS are failing with 400 errors.

以下是对此的jQuery:

$.ajax({
    url: Knuckle.ajaxurl,
    type: \'post\',
    dataType : \'json\',
    data: {
        action: \'kp_filters\',
        nonce: Knuckle.nonce,
        form: serialized_form,
        base_url: base_url
    },
    success: function( response ){
        // console.log(\'===== SUCCESS =====\');
        // console.log(response);

        if( response.results && response.results.length ){
            $(\'.results-item\').remove();
            $(\'.results-pagination\').remove();

            for(i=0; i<response.results.length; i++){
                $(\'.results-list\').append( response.results[i] );
            }

            if( response.pagination && response.pagination.length ){
                $(\'.results-inner\').append( response.pagination );
            }

        } else {
            // No results.
            $(\'.results-item\').remove();
            $(\'.results-pagination\').remove();
        }

    },
    error: function( response ){
        // console.log(\'===== ERROR =====\');
        // console.log(response);
    },
    complete: function( response ){
        // console.log(\'===== COMPLETE =====\');
        // console.log(response);

        // Remove the loading indicator
        $(\'.sk-circle\').removeClass(\'is-loading\');

    }
});
下面是上述代码段的纯Javascript版本,其中包含400个错误:

var serialized_form = encodeURI( kp_serialize(window.mirrored_params) );
var base_url = kp_get_base_url();

var data = {
    url: Knuckle.ajaxurl,
    type: \'post\',
    dataType : \'json\',
    action: \'kp_filters\',
    nonce: Knuckle.nonce,
    form: serialized_form,
    base_url: base_url
};
console.log(\'About to post this data: \');
console.log(data);

var xhr = new XMLHttpRequest();
xhr.open(\'post\', Knuckle.ajaxurl);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");

xhr.onreadystatechange = function() {
    var DONE = 4; // readyState 4 means the request is done.
    var OK = 200; // status 200 is a successful return.
    if( xhr.readyState === DONE ){
        console.log(\'ajax is done: \' + xhr.status);
        if( xhr.status === OK ){
            console.log(xhr.responseText); // \'This is the returned text.\'
        }
    } else {
        console.log(\'Error: \' + xhr.status); // An error occurred during the request.
    }
};

xhr.send(data);
下面是我在控制台中获得的屏幕截图:https://imgur.com/a/y8ULe

我一直在处理数据,并尝试为XMLHttpRequest使用不同的头,但它总是返回400。尝试禁用可能会对其产生影响的插件,但也没有任何效果。

What am I doing wrong with the plain JS AJAX? What is jQuery doing that my code isn\'t?

1 个回复
SO网友:James

谢谢Sally CJ帮助我!问题是数据需要作为序列化字符串(查询字符串)发送,而我的请求标头错误。

这是我现在的最后一个工作函数。很抱歉关于加载动画和滚动到结果列表顶部的无关内容。希望这对将来的人有所帮助。

function kp_submit_filters(){
// console.log( \'START kp_submit_filters()\' );
// console.log( window.mirrored_params );

// Start the loading animation.
var loading_indicator = document.querySelectorAll(\'.sk-circle\');
if( loading_indicator.length ){
    kpAddClass(loading_indicator, \'is-loading\');
}

// Scroll to the top of the results.
var target = document.querySelectorAll(\'.results\');
if (target.length) {
    var target_shape = target[0].getBoundingClientRect();
    var target_position = target_shape.top + window.pageYOffset;
    window.scroll({
        top: target_position - 60,
        left: 0,
        behavior: \'smooth\'
    });

}


// Set up some data to send in the AJAX request.
var base_url = kp_get_base_url();

var data = window.mirrored_params;
    data.action = \'kp_filters\';
    data.nonce = Knuckle.nonce;
    data.base_url = base_url;

// Serialize and encode the data object.
var serialized_data = encodeURI( kp_serialize(data) );

// console.log(\'About to post this data: \');
// console.log( data );
// console.log( serialized_data );

// Make the request object.
var xhr = new XMLHttpRequest();

// Set up what happens with the response - remove existing result items and pagination, add the new search result items and pagination to the DOM, and also stop the loading animation.

xhr.onreadystatechange = function() {
    var DONE = 4; // readyState 4 means the request is done.
    var OK = 200; // status 200 is a successful return.
    if( xhr.readyState === DONE ){
        // console.log(\'ajax is done: \' + xhr.status);
        if( xhr.status === OK ){
            // console.log(\'status is OK\');
            // console.log(xhr);
            // console.log(xhr.responseText); // \'This is the returned text.\'

            var response = JSON.parse( xhr.responseText );
            var result_items = document.querySelectorAll(\'.results-item\');
            var result_pagination = document.querySelectorAll(\'.results-pagination\');
            var results_list = document.querySelectorAll(\'.results-list\');

            if( response.results && response.results.length ){

                // Remove the existing items.
                for( i=0; i<result_items.length; i++){
                    result_items[i].parentNode.removeChild(result_items[i]);
                }

                // Remove the existing pagination.
                for( i=0; i<result_pagination.length; i++){
                    result_pagination[i].parentNode.removeChild(result_pagination[i]);
                }

                // Add the new items and pagination to the DOM.
                if( results_list.length ){
                    for(i=0; i<response.results.length; i++){
                        results_list[0].innerHTML += response.results[i];
                    }

                    if( response.pagination && response.pagination.length ){
                        results_list[0].innerHTML += response.pagination;
                    }

                }



            } else {
                // No results, so just remove the existing items and pagination.

                for( i=0; i<result_items.length; i++){
                    result_items[i].parentNode.removeChild(result_items[i]);
                }

                for( i=0; i<result_pagination.length; i++){
                    result_pagination[i].parentNode.removeChild(result_pagination[i]);
                }

            }

        }

        // Hide the loading animation.
        if( loading_indicator.length ){
            kpRemoveClass(loading_indicator, \'is-loading\');
        }

    } else {
        // console.log(\'Error: \' + xhr.status); // An error occurred during the request.
    }

};

// Send the POST request via AJAX.
xhr.open(\'POST\', Knuckle.ajaxurl, true);
xhr.setRequestHeader(\'Content-Type\', \'application/x-www-form-urlencoded; charset=UTF-8\');
xhr.send( serialized_data );

return false;
}

结束

相关推荐

使用加载了AJAX的ACF表单初始化JS

我正在使用acf\\U表单用ajax编辑我的WP帖子。我已经做好了设置,工作正常,我可以编辑帖子并提交新数据,而无需刷新页面。成功完成后,我还可以加载新内容,而无需刷新页面。但是,acf表单中的任何JS在重新加载后都无法工作。我怎样才能让它工作呢,这是我目前所拥有的(function($) { //// This saves without reloading the page var pathtopage = window.location.pathname;