jQuery.load(), mixed HTTP/HTTPS and Internet Explorer

11,066

You can't get around the mixed-content warning in IE. If the remote resource is available via both HTTP and HTTPS you can make sure your protocols match jQuery.load(location.protocol + '//someurl.com .someClass')


Updated based on the problem being mixed-content in the remote page:

jQuery.load loads the entire responseText into a documentFragment before pulling out the appropriate part indicated by the selector (see jQuery 1.4.4 ajax.js). The entire remote page is parsed as HTML and must go through the browser's security processes; in many ways it's simpler to make sure the response is "clean" by making sure all the protocols match and/or only returning a fragment if that's all you need.

If you won't be modifying the other resource, which would be much more robust, you'll need to replace all occurrences of HTTP with HTTPS (or vice versa) while the remote resource is still just a string. Here's a fragile jQuery plugin as an example of this technique, mostly ripped from jQuery 1.4.4 $.load function:

(function($){
    var http = "http:",
        https = "https:",
        rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
        proto = location.protocol,
        otherProtoUri = new RegExp("\\b" + (proto === http ? https : http) + "(//[a-z\\d.-]+)", "gi");

    $.fn.protocolModifyLoad = function(url, yesIKnowThisIsFragile, selector) {
        var self = this;

        if ( !this.length || !yesIKnowThisIsFragile) {
            return this;
        }

        $.ajax({
            url: url,
            type: "GET",
            dataType: "html",
            complete: function( res, status ) {
                // If successful, inject the HTML into all the matched elements
                if ( status === "success" || status === "notmodified" ) {
                    // Force occurences of the other protocol into the current one
                    var response = res.responseText.replace(otherProtoUri, proto + "$1");

                    // See if a selector was specified
                    self.html( selector ?
                        // Create a dummy div to hold the results
                        jQuery("<div>")
                            // inject the contents of the document in, removing the scripts
                            // to avoid any 'Permission Denied' errors in IE
                            .append(response.replace(rscript, ""))

                            // Locate the specified elements
                            .find(selector) :

                        // If not, just inject the full result
                        response);
                }
            }
        });

        return this;
    };
})(jQuery);

Usage: $('#your > .selector').protocolModifyLoad(location.protocol + '//someurl.com', 'thisIsFragile!!!', '.someClass');

This function omits the callback and params arguments of $.load and the yesIKnowThisIsFragile argument was added as a subtle reminder.

Share:
11,066
grahamb
Author by

grahamb

Front-end developer at Simon Fraser University. Cyclist, Scouter, cat herder, lover of good food and beer. VE7GNB

Updated on June 14, 2022

Comments

  • grahamb
    grahamb almost 2 years

    I'm attempting to load in a remote HTML page using jQuery.load('https://someurl.com .someClass'). The page doing the load is on HTTPS; the remote page is available as both HTTP and HTTPS. Everything works fine in reasonable browsers, but IE is throwing up a mixed HTTP/HTTPS content security warning -- the remote page has CSS and JS included by HTTP links, even when requested as HTTPS. Any clues as how to successfully pull in a mixed-content file in IE without it triggering the warning? Modifying the remote page isn't an option.

    EDIT

    To be clear, I'm attempting to load the remote file over HTTPS. The file contains links to HTTP resources (img, css, js); because I'm providing a selector to .load(), reasonable browsers don't try to parse & execute the document; IE does.