Search code examples
javascriptqtxmlhttprequestqml

Why does XMLHttpRequest responseText not exist?


Reproducible example in QML:

main.cpp

#include <QSsl>

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.0

Window {
    visible: true
    width: 640
    height: 480

    Component.onCompleted: getPage(logResults)

    function logResults(results) {
        console.log("RESULTS: " + results)
    }

    function getPage(callback) {
        var xhttp = new XMLHttpRequest();
        var url = "https://www.google.com/"

        xhttp.onreadystatechange = function() {
            if (xhttp.readyState === 4 && xhttp.status === 200) {
                console.log("calling callback")
                callback(xhttp.responseText)                
            }
        };
        xhttp.open("GET", url);
        xhttp.send();
    }
}

Output I get:

qml: calling callback

Output I expect:

qml: calling callback
qml: RESULTS: <the HTML located at https://www.google.com/>

The xhttp.responseText is not empty or undefined, in fact the console.log() throws no errors. Reformat the code like so:

        xhttp.onreadystatechange = function() {
            if (xhttp.readyState === 4 && xhttp.status === 200) {
                console.log("Am I alive?")
                console.log("response text: " + xhttp.responseText)
                console.log("I am alive")
            }
        };

then I get output:

qml: Am I alive?
qml: I am alive

Why does XMLHttpRequest responseText not exist? Why does it kill the console.log() and not throw an 'undefined' or some other error? Is there a better way to scrape the html from this web page?


Solution

  • In Windows 10 x86_64 with Qt Creator 4.11.0, this function in OP's main.qml does nothing at all:

    function logResults(results) {
        console.log("RESULTS: " + results)
    }
    

    But it works perfectly on Linux. The problem is only in Windows. Nothing is printed in the output panel. No errors, no "qml: something". Nada. As a workaround, this alternative works:

    function logResults(results) {
        console.log("RESULTS Length=", results.length);
        console.log("results.substr=", results.substr(0, 20)); 
    }
    

    It prints something at the "Application output" panel:

    qml: RESULTS Length= 47932
    qml: results.substr= <!doctype html><html
    

    Digging a bit further, we can observe that this:

    console.log("results.substr=", results.substr(0, 32000)); 
    

    Works, but this fails again:

    console.log("results.substr=", results.substr(0, 32800)); 
    

    This suggest that there is a limit about 32K, and console.log() fails silently when the content is larger than this limit. But only in Windows. This smells like a bug somewhere in Qt...

    Edit

    It is not only a problem with console.log(), but in QtCreator's logging. This program fails to print all the output in the Application Output panel:

    #include <QCoreApplication>
    #include <QDebug>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        QString str;
        str.fill('1', 32763);
        qDebug() << str;
        str.fill('2', 32764);
        qDebug() << str;
        return 0;
    }
    

    The '2's string is correctly displayed only when selecting Project > Run Settings > Run in terminal checkbox, but it is omitted when the checkbox is clear. Any message larger than 32763 characters is silenced in Application Output.

    Bug report created: https://bugreports.qt.io/browse/QTCREATORBUG-23454