0

I was refactoring my code to be more "best practices" compliant, such that the javescript files are in the /scripts directory and the image files in the /assy directory which required me to experiment in how a specific function that sends an XMLHttpRequest().open("GET", "/scripts/getpartinformation.php?partNumber=" + PN, true) to retrieve part information from a MySQL DB. I left the original function in index.php and included an identical version in a javascript file as outlined below.

The image HTML calls one of two identical javascript functions as follows:

<area shape="rect" coords="333,316,399,330" href="TopAssy.html" onClick="parent.getassyInformation('100.100002');">
<area shape="rect" coords="341,230,407,246" href="TopAssy.html" onClick="GetassyInformation('100.100001');">

getassyInformation(PN) and GetassyInformation(PN) are the same code but in two different locations. getassyInformation(PN) is in index.php's header as follows:

<script>
function getassyInformation(PN) {
...
</script>
}

GetassyInformation(PN) is in Storage.js, a javascript file in the /scripts directory and is called from the image file's header as:

<script src="../scripts/Storage.js"></script>

The following is their code (upper case 'g' shown):

function GetassyInformation(PN) {
alert("entered GetassyInformation()");
    var arrayPosEnum = {
        DESCRIPTION: 0,
        PRICE: 1,
        QUANTITY: 2,
        EXTENDEDPRICE:3
    };
   
    alert("you clicked: " + PN);
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            alert ("readystate is " + this.readyState + " and status is " + this.Status);
            console.log("ResponseText is: " + this.responseText);
            //convert responseText into array at the comma separator
            var dbData = this.responseText.split(',');
            //add default Qty of '1' and Ext Price placeholders to end of array
            dbData.push("1", dbData[arrayPosEnum.PRICE]);
            localStorage.setItem(PN, dbData);
        }else{
            alert ("readystate is " + this.readyState + " and status is " + this.Status);
            console.log({xmlhttp});
        }
    };
    alert("immediately after xmlhttp.onreadystatechange");
    xmlhttp.open("GET", "../scripts/getassyinformation.php?assyNumber=" + PN, true);
    xmlhttp.send();
}

When '100.100002' is clicked, the alert "immediately after xmlhttp.onreadystatechange" is displayed then the code walks through the xmlhttp responses with alerts displaying "readyState is: " 1 through 4 (see the 'else' code) and a key value pair is returned from the MySQL DB in responseText. However, when '100.100001' is clicked, the "immediately after xmlhttp.onreadystatechange" alert is displayed and the "readystate is 1...." alert is displayed and then nothing.

I experimented with XMLHttpRequest.open's URL with the double-dot or no double-dot in both versions and get the same result, failure when '100.100001' is clicked and success when '100.100002' is clicked. Apache finds getassyinformation.php, with or without double-dot before /scripts when '100.100002' is clicked.

When I click on '100.100001' (failure) I get no error message in apache_error.log, but I get the following entries in access.log:

::1 - - [12/Jul/2020:15:43:51 -0500] "GET /scripts/getpartinformation.php?partNumber=100.100001 HTTP/1.1" 200 28
::1 - - [12/Jul/2020:15:43:51 -0500] "GET /scripts/Storage.js HTTP/1.1" 304 -

When I click on '100.100002' (success) I get the following entries in access.log:

::1 - - [12/Jul/2020:15:45:51 -0500] "GET /scripts/getpartinformation.php?partNumber=100.100002 HTTP/1.1" 200 25
::1 - - [12/Jul/2020:15:45:53 -0500] "GET /scripts/Storage.js HTTP/1.1" 304 -

Common Log Format indicates that '28' and '25' at the end of each line "indicates the size of the object returned to the client". This makes sense because the responseText shown in console.log is: "key is: 100.100002 and item is: base assy,50.00" or 25 characters. The value '28' shown for the failed PN (100.100001) makes sense as it would report the following in console.log if it succeeded: "key is: 100.100001 and item is: cradle assy,125.00" or 28 characters.

Does anyone have an idea as to what could be happening to what appears to be the key value pair returned from MySQL when '100.100001' is clicked? I'm stumped as to why '200' is reported for both, yet clicking '100.100001' doesn't step through the readyStates and the value is lost but appears to have been sent from the access.log report of a status code of '200' and '28' characters.

Barmar
  • 741,623
  • 53
  • 500
  • 612
Jeff
  • 431
  • 4
  • 16
  • 1
    Check the Network tab of DevTools to see what the response to the AJAX request was. – Barmar Jul 13 '20 at 00:43
  • Sorry for not including that. For the failed getpartinformation.php?partNumber=100.100001 status is "(canceled)", for 100.100002 it is "200". Both show Type as "xhr", Initiator as their respective "xmlhttp.send();" commands, but size for the failed call is 0B. I didn't even think of that and am looking up "AJAX" and "canceled" now. Thanks for bringing that up. – Jeff Jul 13 '20 at 14:39
  • I think cancelled means that the browser has abandoned the AJAX request. A common reason for this would be if the page is reloaded. – Barmar Jul 13 '20 at 15:03
  • But why would the same request be fulfilled while the other canceled when they come from the same origin ([Same-origin policy](https://en.wikipedia.org/wiki/Same-origin_policy)), at least as far as I can tell? – Jeff Jul 13 '20 at 16:32
  • It has nothing to do with the same-origin policy, that would report an error. – Barmar Jul 13 '20 at 16:40
  • OK. The network tab shows essentially the same process for both failed and successful calls except for the canceled vs 200. – Jeff Jul 13 '20 at 16:49
  • I'm not sure why that would be happening if the code in the functions is essentially the same. – Barmar Jul 13 '20 at 16:53
  • I do notice that Initiator indicates VMxx Storage.js: 193 where 193 is xmlhttp.send(); [Chrome Development Tool: VM file from javascript](https://stackoverflow.com/questions/17367560/chrome-development-tool-vm-file-from-javascript) . Something to look into. – Jeff Jul 13 '20 at 17:56
  • `VM` means JavaScript code that's created dynamically, perhaps using `eval()`. – Barmar Jul 13 '20 at 17:57

0 Answers0