79416327

Date: 2025-02-05 22:22:11
Score: 0.5
Natty:
Report link

With David's help, I found a few issues with my code.

I had dataType: 'json' in my ajax set up. This is for the expected response, not the request. I removed it.

I used JSON.stringify( err ) to open up the xhr error object. This revealed the error I was missing originally: "Failed to read the 'responseXML' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'document' (was 'blob')."

I removed xhrFields: { responseType: 'blob' } from my ajax set up. This allowed the xml file from the server to be read and land in the success handler. But still, the file was not loading.

I added a console log of xhr.getAllResponseHeaders() which revealed that the Content-Disposition was missing from xhr. I switched instead to content-type to discern if the response was an XML file (application/octet-stream) or JSON (application/json).

After this, when trying to convert the blob to a file, I got this error: "Failed to execute 'createObjectURL' on 'URL': Overload resolution failed."

This question gave me the final answer I needed. The body of the response has to be explicitly converted to a blob object.

Here is the final, working code. (I have not tested the IE and Safari hacks.)

$.ajax( {
    url: m_APIURL,
    method: 'POST', type: 'POST',
    data: JSON.stringify( formData ),
    contentType: 'application/json',
    crossDomain: true,
    success: function( body, status, xhr )
    {
        console.log( "success! headers=" + xhr.getAllResponseHeaders() + " xhr=" + JSON.stringify( xhr ) ); // DEBUG
        var header = xhr.getResponseHeader( 'content-type' );
        if( header && header.indexOf( 'octet-stream' ) !== -1 )
        {
            // If success, returns a file. Trigger the file save.
            var filename = 'license.xml';
            var blob = new Blob( [body], { type: "application/octetstream" } );
            if( typeof window.navigator.msSaveBlob !== 'undefined' )
            {
                // IE hack.
                window.navigator.msSaveBlob( blob, filename );
            }
            else
            {
                var URL = window.URL || window.webkitURL;
                var downloadUrl = URL.createObjectURL( blob );
                var a = document.createElement( "a" );
                if( typeof a.download === 'undefined' )
                {
                    // Safari hack.
                    window.location.href = downloadUrl;
                }
                else
                {
                    a.href = downloadUrl;
                    a.download = filename;
                    document.body.appendChild( a );
                    a.click();
                }
                setTimeout( function() { URL.revokeObjectURL( downloadUrl ); }, 100 );
            }
        }
        else
        {
            // If validation failed, returns JSON. Display the errors.
            if( body )
            {
                if( ( body.ErrorMessage && body.ErrorMessage != "OK" ) || ( !body.Content || body.Content == '' ) )
                {
                    alert( "Error getting license file. " + body.ErrorMessage );
                }
                else
                {
                    alert( "Error getting license file. " + body.Content );
                }
            }
            else
            {
                console.log( "returned null" ); //DEBUG
                alert( "Error getting license file." );
            }
        }
    },
    error: function( err )
    {
        if( err != null && err.length > 0 )
        {
            console.log( "Error in response: " + JSON.stringify( err ) );
        }
        else
        {
            console.log( "Error in response but nothing returned." );
        }
    }
} );
Reasons:
  • Blacklisted phrase (0.5): I need
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: Trint