首页 > 解决方案 > XMLHttpRequest 在 WordPress 中不起作用

问题描述

我正在尝试使用 XMLHttpRequest 将变量发送到服务器。

我在本地的非 Wordpress 文件上对其进行了测试,并且可以正常工作。但是在生产中,在我的 Wordpress 文件中,onreadystatechange AJAX 状态没有达到 200。

在 Wordpress 中进行 XMLHttpRequesting 时有什么需要注意的吗?

我有以下代码用于使用 XMLHTTP Request 向服务器发送数据,但它不起作用我不知道为什么?我收到以下错误:

VM704:1 POST http://localhost/amt/wp-admin/admin-ajax.php 400(错误请求)

这是我的 WordPress 代码:

add_action('wp_ajax_csv_file', 'csv_file');

add_action('wp_ajax_nopriv_csv_file', 'csv_file');

function csv_file()
{
if($_POST['rtype'] == 'enr_data'){
        set_time_limit(0);
        ob_implicit_flush(true);
        ob_end_flush();

        for ($i = 0; $i < 10; $i++) {
            //Hard work!!
            sleep(1);
            $p = ($i + 1) * 10; //Progress
            $response = array('message' => $p . '% complete. server time: ' . date("h:i:s", time()),
                'progress' => $p);

            echo json_encode($response);
        }

        sleep(1);
        $response = array('message' => 'Complete',
            'progress' => 100);

        echo json_encode($response);

        die();
        }
}

function ajax_stream() {
            if (!window.XMLHttpRequest) {
                alert("Your browser does not support the native XMLHttpRequest object.");
                return;
            }
            try {
                var xhr = new XMLHttpRequest();
                xhr.previous_text = '';
                xhr.responseType = "text";

                xhr.onerror = function() {
                    alert("[XHR] Fatal Error.");
                };
                xhr.onreadystatechange = function() {
                    try {
                        if (xhr.readyState == 4) {
                            alert('[XHR] Done')
                        } else if (xhr.readyState > 2) {
                            var new_response = xhr.responseText.substring(xhr.previous_text.length);
                            var result = JSON.parse(new_response);

                            document.getElementById("divProgress").innerHTML += result.message + '<br />';
                            document.getElementById('progressor').style.width = result.progress + "%";

                            xhr.previous_text = xhr.responseText;
                        }
                    } catch (e) {
                        alert("[XHR STATECHANGE] Exception: " + e);
                    }
                };
                var data = "action=csv_file&rtype=enr_data";
                xhr.open("POST", ajaxurl, true);
                xhr.send(data);
                console.log(xhr);
            } catch (e) {
                alert("[XHR REQUEST] Exception: " + e);
            }
        }
#divProgress {
            border: 2px solid #ddd;
            padding: 10px;
            width: 300px;
            height: 265px;
            margin-top: 10px;
            overflow: auto;
            background: #f5f5f5;
        }
        
        #progress_wrapper {
            border: 2px solid #ddd;
            width: 321px;
            height: 20px;
            overflow: auto;
            background: #f5f5f5;
            margin-top: 10px;
        }
        
        #progressor {
            background: #07c;
            width: 0%;
            height: 100%;
            -webkit-transition: all 1s linear;
            -moz-transition: all 1s linear;
            -o-transition: all 1s linear;
            transition: all 1s linear;
        }
        
        .demo_container {
            width: 680px;
            margin: 0 auto;
            padding: 30px;
            background: #FFF;
            margin-top: 50px;
        }
        
        .my-btn,
        .my-btn2 {
            width: 297px;
            margin-top: 22px;
            float: none;
            display: block;
        }
        
        h1 {
            font-size: 22px;
            margin-bottom: 20px;
        }
        
        .float_left {
            float: left;
        }
        
        .float_right {
            float: right;
        }
        
        .demo_container::after {
            content: "";
            clear: both;
            display: block;
        }
        
        .ghost-btn.active {
            border: 2px solid #D23725;
            color: #D23725;
        }
        
        .ghost-btn {
            display: inline-block;
            text-decoration: none;
            border: 2px solid #3b8dbd;
            line-height: 15px;
            color: #3b8dbd;
            -webkit-border-radius: 3px;
            -webkit-background-clip: padding-box;
            -moz-border-radius: 3px;
            -moz-background-clip: padding;
            border-radius: 3px;
            background-clip: padding-box;
            font-size: 15px;
            padding: .6em 1.5em;
            -webkit-transition: all 0.2s ease-out;
            -moz-transition: all 0.2s ease-out;
            -o-transition: all 0.2s ease-out;
            transition: all 0.2s ease-out;
            background: #ffffff;
            -webkit-box-sizing: content-box;
            -moz-box-sizing: content-box;
            box-sizing: content-box;
            cursor: pointer;
            zoom: 1;
            -webkit-backface-visibility: hidden;
            position: relative;
            margin-right: 10px;
        }
        
        .ghost-btn:hover {
            -webkit-transition: 0.2s ease;
            -moz-transition: 0.2s ease;
            -o-transition: 0.2s ease;
            transition: 0.2s ease;
            background-color: #3b8dbd;
            color: #ffffff;
        }
        
        .ghost-btn:focus {
            outline: none;
        }
        
        .ghost-btn.active {
            border: 2px solid #D23725;
            color: #D23725;
        }
        
        .ghost-btn.active:hover {
            border: 2px solid #D23725;
            background: #FFF;
        }
        
        .method_wrappers {
            margin-bottom: 20px;
        }
<div class="demo_container">
        <div class='method_wrappers'>
            <a class='ghost-btn active' href='#'>XHR Method</a>
            <a class='ghost-btn' href='../example2/index.html'>Iframe Method</a>
        </div>
        <h1>AJAX progress bar for PHP script without polling (XHR method)</h1>
        <div class='float_left'>
            <h3>Progress Bar</h3>
            <div id='progress_wrapper'>
                <div id="progressor"></div>
            </div>
            <a onclick="ajax_stream();" class='my-btn'>Start Ajax Streaming</a>
        </div>
        <div class='float_right'>
            <h3>Log</h3>
            <div id="divProgress"></div>
        </div>
    </div>

标签: javascriptwordpressxmlhttprequest

解决方案


当使用 XHR 而不是 jQuery/AJAX 请求时,我发现actionajaxurl.

var xhr = new XMLHttpRequest();
var url = ajaxurl + '?action=csv_file';

xhr.open( 'POST', url, true );

将数据传递给请求的方法略有不同,但 95% 的时间我使用一个简单的对象来查询字符串函数:

// Convert an Object into a Query String
function objectToQueryString(obj){
    return Object.keys(obj).map(key => key + '=' + obj[key]).join('&');
}

这在实践中将变成一个简单的数据对象

var data = {
    'post_id': ajax_object.post_id,
    'rtype': 'enr_data',
    'field': element.getAttribute('data-field'),
};

变成一个简单的查询字符串:

post_id=1234&rtype=enr_data&field=bar

这让我可以将数据作为字符串传递给目标函数:

var dataString = objectToQueryString( data );
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(dataString);

对于更大或更复杂的任务,您实际上也可以有效地将整个事情包装在Promise中,例如,如果我需要上传少量文件并逐个传递这些文件以调整大小,我会这样做。


推荐阅读