Search code examples
javascriptjsonrestxmlhttprequestfirefox-developer-tools

How To See What The Problem Is With XmlHttpRequest


I wrote a simple REST API in ASP.NET that returns some data in json format. I then tried to write some javascript to use it and have hit a brick wall. When I use a demo API my code works fine but when I try to use my own API, it fails and I don't know how to get any information about why. Here is my code demonstrating the problem (html with javascript):

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
        <meta http-equiv="Pragma" content="no-cache" />
        <meta http-equiv="Expires" content="0" />
    </head>
    <body>
        <h2>Test Output:</h2>
        <div id="testOutput"></div>
    </body>
    
    <script language="javascript">
        function listAllProperties(o) {
            var objectToInspect;     
            var result = [];
        
            for(objectToInspect = o; objectToInspect !== null; 
                   objectToInspect = Object.getPrototypeOf(objectToInspect)) {  
                result = result.concat(
                    Object.getOwnPropertyNames(objectToInspect)
                );  
            }
        
            return result; 
        }
    </script>
    <script language="javascript">
        const testOutput = document.getElementById('testOutput')
    
        var request = new XMLHttpRequest()
        request.open('GET', 'https://ghibliapi.herokuapp.com/films', true)  // with this line, "In Function" is printed
        //request.open('GET', 'http://local.api.com/moviesearch/crash', true)  // ...but if you use this line instead, "In Function" is NOT printed
        request.onload = function () {
            testOutput.innerHTML = "In Function with https://ghibliapi.herokuapp.com/films <br /><br />"
        }
        request.send()
    
        var request2 = new XMLHttpRequest()
        request2.open('GET', 'http://local.api.com/moviesearch/crash', true)  // As stated in the comment above, "In Function" is NOT printed
        request2.onload = function () {
            testOutput.innerHTML += "In Function with http://local.api.com/moviesearch/crash <br /><br />"
        }
    
        function handleEvent(progressEventObject) {
            testOutput.innerHTML += "Failed with http://local.api.com/moviesearch/crash <br /><br />"
            testOutput.innerHTML += "<b>Error Details</b> <br /><br />"
            listAllProperties(progressEventObject).forEach((prop) => testOutput.innerHTML += `${prop} = ${progressEventObject[prop]}<br /><br />`);
            testOutput.innerHTML += "<b>Request Details</b> <br /><br />"
            listAllProperties(progressEventObject.currentTarget).forEach((prop) => testOutput.innerHTML += `${prop} = ${progressEventObject[prop]}<br /><br />`);
        }
    
        request2.addEventListener('error', handleEvent);
        request2.send()
    </script>
    </html>

In the first bit of code after "var request = new XMLHttpRequest()" you can see that I am using the demo API at "https://ghibliapi.herokuapp.com/films" and this works but then you can see below that with "request2" I try to use my own API (running on my local machine using IIS, accessible to me locally at http://local.api.com/moviesearch/{searchTerm}). In monitoring the request to the API I wrote, using the "Network" tab in the Firefox Developer Tools, I can see nothing wrong with the response (the raw response is pasted with headers here).

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 24 Nov 2020 01:11:12 GMT
Content-Length: 69

{"Count":1,"ItemList":["Wedding Crashers 2005 Uncorked Edition"]}

According to the Network tab in the Firefox Developer Tools, this response came back after 286 milliseconds of waiting.

I cannot see anything helpful in the print-out of the progressEvent object or the XmlHttpRequest object I do towards the end of my javascript (but I will paste the output below in case it is useful in helping to debug this).

Error Details:

"isTrusted" = "true"
"lengthComputable" = "false"
"loaded" = "0"
"total" = "0"
"constructor" = "function ProgressEvent() { [native code] }"
"composedPath" = "function composedPath() { [native code] }"
"stopPropagation" = "function stopPropagation() { [native code] }"
"stopImmediatePropagation" = "function stopImmediatePropagation() { [native code] }"
"preventDefault" = "function preventDefault() { [native code] }"
"initEvent" = "function initEvent() { [native code] }"
"type" = "error"
"target" = "[object XMLHttpRequest]"
"srcElement" = "[object XMLHttpRequest]"
"currentTarget" = "[object XMLHttpRequest]"
"eventPhase" = "2"
"bubbles" = "false"
"cancelable" = "false"
"returnValue" = "true"
"defaultPrevented" = "false"
"composed" = "false"
"timeStamp" = "382"
"cancelBubble" = "false"
"originalTarget" = "[object XMLHttpRequest]"
"explicitOriginalTarget" = "[object XMLHttpRequest]"
"NONE" = "0"
"CAPTURING_PHASE" = "1"
"AT_TARGET" = "2"
"BUBBLING_PHASE" = "3"
"ALT_MASK" = "1"
"CONTROL_MASK" = "2"
"SHIFT_MASK" = "4"
"META_MASK" = "8"
"constructor" = "function ProgressEvent() { [native code] }"
"toString" = "function toString() { [native code] }"
"toLocaleString" = "function toLocaleString() { [native code] }"
"valueOf" = "function valueOf() { [native code] }"
"hasOwnProperty" = "function hasOwnProperty() { [native code] }"
"isPrototypeOf" = "function isPrototypeOf() { [native code] }"
"propertyIsEnumerable" = "function propertyIsEnumerable() { [native code] }"
"__defineGetter__" = "function __defineGetter__() { [native code] }"
"__defineSetter__" = "function __defineSetter__() { [native code] }"
"__lookupGetter__" = "function __lookupGetter__() { [native code] }"
"__lookupSetter__" = "function __lookupSetter__() { [native code] }"
"__proto__" = "[object ProgressEvent]"
"constructor" = "function ProgressEvent() { [native code] }"

Request Details:

"open" = "undefined"
"setRequestHeader" = "undefined"
"send" = "undefined"
"abort" = "undefined"
"getResponseHeader" = "undefined"
"getAllResponseHeaders" = "undefined"
"overrideMimeType" = "undefined"
"onreadystatechange" = "undefined"
"readyState" = "undefined"
"timeout" = "undefined"
"withCredentials" = "undefined"
"upload" = "undefined"
"responseURL" = "undefined"
"status" = "undefined"
"statusText" = "undefined"
"responseType" = "undefined"
"response" = "undefined"
"responseText" = "undefined"
"responseXML" = "undefined"
"mozAnon" = "undefined"
"mozSystem" = "undefined"
"UNSENT" = "undefined"
"OPENED" = "undefined"
"HEADERS_RECEIVED" = "undefined"
"LOADING" = "undefined"
"DONE" = "undefined"
"constructor" = "function ProgressEvent() { [native code] }"
"onloadstart" = "undefined"
"onprogress" = "undefined"
"onabort" = "undefined"
"onerror" = "undefined"
"onload" = "undefined"
"ontimeout" = "undefined"
"onloadend" = "undefined"
"constructor" = "function ProgressEvent() { [native code] }"
"addEventListener" = "undefined"
"removeEventListener" = "undefined"
"dispatchEvent" = "undefined"
"constructor" = "function ProgressEvent() { [native code] }"
"toString" = "function toString() { [native code] }"
"toLocaleString" = "function toLocaleString() { [native code] }"
"valueOf" = "function valueOf() { [native code] }"
"hasOwnProperty" = "function hasOwnProperty() { [native code] }"
"isPrototypeOf" = "function isPrototypeOf() { [native code] }"
"propertyIsEnumerable" = "function propertyIsEnumerable() { [native code] }"
"__defineGetter__" = "function __defineGetter__() { [native code] }"
"__defineSetter__" = "function __defineSetter__() { [native code] }"
"__lookupGetter__" = "function __lookupGetter__() { [native code] }"
"__lookupSetter__" = "function __lookupSetter__() { [native code] }"
"__proto__" = "[object ProgressEvent]"
"constructor" = "function ProgressEvent() { [native code] }"

Lastly, I see nothing being written to the browser console when the request to my API results the error event listener function being called.

Thank you for taking the time to read this and any tips you can give me on how to proceed.


Solution

  • As Bravo suggested in their comment, I checked the development tools console and saw the CORS error:

    "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at localhost/moviesearch/crash. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)."

    The answer at the following post is a really awesome/easy solution for this problem: Setting Access-Control-Allow-Origin in ASP.Net MVC - simplest possible method

    Thank you Bravo!