【问题标题】:XMLHttpRequest onload not called未调用 XMLHttpRequest onload
【发布时间】:2023-03-17 08:05:01
【问题描述】:

我是 JS 的新手。 据我了解,在函数createNewGetXHR() 中创建的XMLHttpRequest 的新实例必须在发送请求后触发onload 回调函数。现在它可以在不触发回调的情况下工作。但是,如果我在postData() 中评论 do-while 循环(字符串 55 和 63),回调开始工作(如何在循环中创建新的 GET 请求,以便我可以控制从该循环退出?

    <script>
        function sleep(ms) {
            ms += new Date().getTime();
            while (new Date() < ms){}
        }
        function createNewGetXHR(uniqId, server_state) {
            alert("In createNewGetXHR()");
            var url = "http://localhost:8080/api/users?uniqId=" + uniqId;
            var xhr = new XMLHttpRequest();

            xhr.open("GET", url, true);
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.onload = function () {
                alert("Fired onload callback");
                if (xhr.readyState === xhr.DONE) {
                    if (xhr.status === 200) {
                        var server_resp = xhr.responseText;

                        alert("server_resp: " + server_resp);
                        if (server_resp !== "-") {
                            server_state.working = false;
                            server_state.response_html = server_resp;
                        }
                    }
                }
            };

            return xhr;
        }
        function postData() {
            // Get data from froms
            var name = document.getElementById('name').value;
            var surname = document.getElementById('surname').value;
            var action = document.getElementById('action').value;
            // Make json from data
            var data = JSON.stringify({"action": action, "user": {"name": name, "surname": surname}});
            // Prepare request
            var url = "http://localhost:8080/api/users";
            var xhr = new XMLHttpRequest();

            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-Type", "application/json");
            // Handle server response
            xhr.onload = function () {
                if (xhr.readyState === xhr.DONE) {
                    if (xhr.status === 200) {
                        alert("Server is working. Please wait for the answer!");

                        var REFRESH_RATE = 2000;
                        var uniqId = xhr.responseText;
                        var server_state = { working: true, response_html: "default" };
                        var reqs_holder = [];

                        // Checking for the server answer every $REFRESH_RATE
                        do { // (1) if comment out it - code start working(once)
                            sleep(REFRESH_RATE);

                            var new_req = createNewGetXHR(uniqId, server_state);

                            reqs_holder.push(new_req);
                            new_req.send();
                            //alert("Send GET");
                        } while (server_state.working); // (2) if comment out it - code start working(once)

                        document.write(result_html);
                    }
                }
            };
            // Make post request
            xhr.send(data);
        }
    </script>

【问题讨论】:

  • sleep(REFRESH_RATE); 太可怕了,它所做的只是锁定浏览器,无法执行任何操作

标签: javascript post get xmlhttprequest


【解决方案1】:

据我了解,当代码在循环内旋转时,不会执行像 onload 这样的回调。由于循环的退出条件是在回调中设置的,我们得到一个无限循环。解决方案是一个尾递归函数,如果服务器仍然没有处理请求,它会在延迟后调用自己。

    <script>
        function sleep(ms) {
            ms += new Date().getTime();
            while (new Date() < ms){}
        }
        function waitForResponse(uniqId, refresh_rate) {
            var url = "http://localhost:8080/api/users?uniqId=" + uniqId;
            var xhr = new XMLHttpRequest();

            xhr.open("GET", url, false);
            xhr.onload = function () {
                if (xhr.readyState === xhr.DONE && xhr.status === 200) {
                    var server_resp = xhr.responseText;

                    if (server_resp === "-") {
                        sleep(refresh_rate);
                        waitForResponse(uniqId, refresh_rate);
                    }
                    else
                        document.write(server_resp);
                }
            };
            xhr.send();
        }
        function postData() {
            /* Get data from froms the forms */
            var name = document.getElementById('name').value;
            var surname = document.getElementById('surname').value;
            var action = document.getElementById('action').value;
            var data = JSON.stringify({"action": action,
                "user": {"name": name, "surname": surname}}); // make json from data

            /* Prepare request */
            var url = "http://localhost:8080/api/users";
            var xhr = new XMLHttpRequest();

            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-Type", "application/json");
            xhr.onload = function () { // handle server response
                if (xhr.readyState === xhr.DONE && xhr.status === 200) {
                    alert("Server is working. Please wait for the answer!");

                    var REFRESH_RATE = 1000;
                    var uniqId = xhr.responseText;

                    waitForResponse(uniqId, REFRESH_RATE);
                }
            };
            xhr.send(data); // make post request
        }
    </script>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-25
    • 2022-01-20
    • 2019-12-06
    • 1970-01-01
    • 2017-10-12
    • 1970-01-01
    • 2013-06-29
    • 2016-02-09
    相关资源
    最近更新 更多