2

XMLHttpRequest() and fetch() in Javascript(let) returns nothing sometimes

I would first like to acknowledge that I might be getting something absolutely wrong here.

The code below will have the following results in chrome (accounted for CORS):

  • results[0-8].fetch = "..." // contains something
  • results[0-8].xhttp = "..."

but will have the following results in Tasker:

  • results[0-4].fetch = "" // undefined
  • results[0-4].xhttp = ""
  • results[5-8].fetch = "..."
  • results[5-8].xhttp = "..."
var results = [];
var notWorkingLinks = [
        "http://wifij01us.magichue.net/app/sendRequestCommand/ZG001", 
        "http://wifij01us.magichue.net", 
        "https://fcklinks.fr", 
        "https://fcklinks.fr/index.html",
        "https://google.com"
];
var workingLinks = [
        "https://fcklinks.fr/php.php", 
        "https://fcklinks.fr/css.css", 
        "https://fcklinks.fr/js.js",
        "https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"
]

notWorkingLinks.forEach((url) => {
        results.push(get(url));
});

workingLinks.forEach((url) => {
        results.push(get(url));
});

function get(url) {
        var result = {};
        fetch(url, {
                method: "GET"
        }).then(async (response) => { 
                if (response) {
                        await response.text().then((r) => { 
                                result["fetch"] = r; 
                        });
                }
        });

        let xhttp = new XMLHttpRequest();
        xhttp.open("GET", url, true);
        xhttp.onload = () => { 
                if (xhttp.response) {
                        result["xhttp"] = xhttp.responseText; 
                }
        };
        xhttp.send();

        return result;
}


Few things to note:

  • An observation will be that something is only returned if the URL doesn't end with "html" or a sever directory.
  • The results here are the same with a POST request too.
  • I currently have no workaround other than to use a plugin or create a php server that requests info then relays it onto the page.
  • It doesn't seem to be a special character issue as it works with the js, css, and php files.
  • The request seems to still go through successfully, just without a response.
  • I'm running Tasker 5.7.2 on Andoid 9.0, with May security patches, on a Galaxy S10, without root

3 replies

JL

Here's the Tasker XML:

<TaskerData sr="" dvi="1" tv="5.7.2">
        <Task sr="task25">
                <cdate>1560874032029</cdate>
                <edate>1560877311953</edate>
                <id>25</id>
                <nme>bruh</nme>
                <pri>100</pri>
                <Action sr="act0" ve="7">
                        <code>547</code>
                        <Str sr="arg0" ve="3">%token</Str>
                        <Str sr="arg1" ve="3">eyJ0eXAiOiJKc29uV2ViVG9rZW4iLCJhbGciOiJIUzUxMiJ9.eyJjZHBpZCI6IlpHMDAxIiwidW5pSUQiOiJkMmNmYmQzYy02YThlLTExZTktOWNiZi0wMDE2M2UwMDZjYjMiLCJ1c2VySUQiOiJibGF4YmxhMTIzQGdtYWlsLmNvbSIsInNlcnZlckNvZGUiOiJVUyIsImV4cGlyZURhdGUiOjE1NzIxMDE3MzEyNDQsImNsaWVudElEIjoiM2QyMGRlZTFlYWFkZjFiM3Vua25vd24iLCJyZWZyZXNoRGF0ZSI6MTU2NjkxNzczMTI0NCwibG9naW5EYXRlIjoxNTU2NTQ5NzMxMjQ0fQ.4Ay3rQlNl0VaQGpPiuFJ_dGU5XEVWok2pWh4K-BJ738OmUAO_QtgtODztfV1mXUEptrgvAe4_pThZf83ydxpRg</Str>
                        <Int sr="arg2" val="0"/>
                        <Int sr="arg3" val="0"/>
                        <Int sr="arg4" val="0"/>
                </Action>
                <Action sr="act1" ve="7">
                        <code>129</code>
                        <Str sr="arg0" ve="3">// XMLHttpRequest() Variant

var xhttp = new XMLHttpRequest(); 
var token = local("token");
xhttp.open("POST", "http://wifij01us.magichue.net/app/sendRequestCommand/ZG001", true); 
xhttp.setRequestHeader("Accept-Language", "en-GB"); xhttp.setRequestHeader("Accept", "application/json"); 
xhttp.setRequestHeader("x_token", token); 
xhttp.onload = function () {
        var response = xhttp.response;
        if (response.includes("814423")) 
                setLocal("light", "on"); 
        else if (response.includes("814424")) 
                setLocal("light", "off");
        alert(local("light"));
        exit();
};
xhttp.send(JSON.stringify({ "macAddress":"600194CFBE6A", "hexData":"81 8a 8b 96 ",      "responseCount":14 }));</Str>
                        <Str sr="arg1" ve="3"/>
                        <Int sr="arg2" val="0"/>
                        <Int sr="arg3" val="45"/>
                </Action>
                <Action sr="act2" ve="7">
                        <code>129</code>
                        <Str sr="arg0" ve="3">// fetch() Variant

var token = local("token");
fetch("http://wifij01us.magichue.net/app/sendRequestCommand/ZG001", {
        method: "POST", 
        headers: {
        "Accept": "application/json",
                "Accept-Language": "en-GB",
                "x_token": token,
                "Content-Type": "application/json; charset=utf-8"
        },
        body: JSON.stringify({ "macAddress":"600194CFBE6A", "hexData":"81 8a 8b 96 ", "responseCount":14 })
})
.then(async (response) =&gt; {
        try { 
                let json = await response.json();
                if (json.data.includes("814423"))
                        setLocal("light", "on"); 
                else if (json.data.includes("814424"))
                        setLocal("light", "off"); 
        } catch (e) { 
                alert(e);
                exit();
        }
        alert(local("light"));
        exit();
});</Str>
                        <Str sr="arg1" ve="3"/>
                        <Int sr="arg2" val="0"/>
                        <Int sr="arg3" val="45"/>
                </Action>
                <Action sr="act3" ve="7">
                        <code>129</code>
                        <Str sr="arg0" ve="3">var results = [];
var resultsStr = "";
var notWorkingLinks = [
        "http://wifij01us.magichue.net/app/sendRequestCommand/ZG001", 
        "http://wifij01us.magichue.net", 
        "https://fcklinks.fr", 
        "https://fcklinks.fr/index.html",
        "https://google.com"
];
var workingLinks = [
        "https://fcklinks.fr/php.php", 
        "https://fcklinks.fr/css.css", 
        "https://fcklinks.fr/js.js",
        "https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"
]

notWorkingLinks.forEach((url) =&gt; {
        get(url, false);
});

workingLinks.forEach((url) =&gt; {
        get(url, true);
});

function get(url, working) {
        var result = {};
        fetch(url, {
                method: "GET"
        }).then(async (response) =&gt; { 
                if (response) {
                        await response.text().then((r) =&gt; { 
                                result["fetch"] = r.substring(0, 32); 
                                                                let xhttp = new XMLHttpRequest();
                                xhttp.open("GET", url, true);
                                xhttp.onload = () =&gt; { 
                                        if (xhttp.response) {
                                                result["xhttp"] = xhttp.responseText.substring(0, 32); 
                                                results.push(result);
                                                                                                resultsStr = resultsStr + " (" + url + "): " + result.fetch + " | " + result.xhttp + " | ";
setLocal("results_str", resultsStr);
if (results.length == workingLinks.length) { alert("received data: " + resultsStr); exit(); }
                                        }
                                };
                                xhttp.send();
                        });
                }
        });

        
}</Str>
                        <Str sr="arg1" ve="3"/>
                        <Int sr="arg2" val="0"/>
                        <Int sr="arg3" val="10"/>
                </Action>
        </Task>
</TaskerData>

For the HTTP Request, can you guide me on how to use it? It doesn't seem to be working with me just pouring a JSON into the headers and body field. The web server just throws an error that says that the token is invalid, which is a generic error for if there isn't any headers passed too. Do I need to stringify it first?

JL

I have a specific use case that does a POST request using some custom headers (for a smart bulb). I tried using the Tasker HTTP action but couldn't find a way to attach custom headers. I tried using other 3rd part REST plugins but to no avail as well. This js method works fine for me when doing the POST request, but not when data is expected to be returned in the response.

Here's the exact code for the use case: 

// XMLHttpRequest() Variant

var xhttp = new XMLHttpRequest(); 
var token = ""; // redacted
xhttp.open("POST", "http://wifij01us.magichue.net/app/sendRequestCommand/ZG001", true); 
xhttp.setRequestHeader("Accept-Language", "en-GB"); xhttp.setRequestHeader("Accept", "application/json"); 
xhttp.setRequestHeader("x_token", token); 
xhttp.onload = function () {
        var response = xhttp.response;
        if (response.includes("814423")) 
                setLocal("light", "on"); 
        else if (response.includes("814424")) 
                setLocal("light", "off");
        exit();
};
xhttp.send(JSON.stringify({ "macAddress":"600194CFBE6A", "hexData":"81 8a 8b 96 ",      "responseCount":14 }));



// fetch() Variant

var token = ""; // redacted
fetch("http://wifij01us.magichue.net/app/sendRequestCommand/ZG001", {
        method: "POST", 
        headers: {
        "Accept": "application/json",
                "Accept-Language": "en-GB",
                "x_token": token,
                "Content-Type": "application/json; charset=utf-8"
        },
        body: JSON.stringify({ "macAddress":"600194CFBE6A", "hexData":"81 8a 8b 96 ", "responseCount":14 })
})
.then(async (response) => {
        let json = await response.json();
        if (json.data.includes("814423"))
                setLocal("light", "on"); 
        else if (json.data.includes("814424"))
                setLocal("light", "off"); 
        exit();
});

I see, thanks. Just so you know, the Tasker beta (https://joaoapps.com/beta-testing/) has a new HTTP Request action that allows custom headers. Maybe that will work :)

As for your use case, could you please make a small test task just to exemplify the issue so I could easily reproduce it? Thanks in advance!

Just out curiosity, why are you not doing those requests in the Tasker HTTP action instead?