【问题标题】:jQuery.load(), mixed HTTP/HTTPS and Internet ExplorerjQuery.load(),混合 HTTP/HTTPS 和 Internet Explorer
【发布时间】:2011-11-23 14:00:36
【问题描述】:

我正在尝试使用 jQuery.load('https://someurl.com .someClass') 加载远程 HTML 页面。进行加载的页面在 HTTPS 上;远程页面可作为 HTTP 和 HTTPS 使用。在合理的浏览器中一切正常,但 IE 抛出混合的 HTTP/HTTPS 内容安全警告——远程页面的 HTTP 链接包含 CSS 和 JS,即使请求为 HTTPS。关于如何在 IE 中成功拉入混合内容文件而不触发警告的任何线索?修改远程页面不是一种选择。

编辑

明确地说,我正在尝试通过 HTTPS 加载远程文件。该文件包含指向 HTTP 资源(img、css、js)的链接;因为我为.load() 提供了一个选择器,合理的浏览器不会尝试解析和执行文档; IE 可以。

【问题讨论】:

  • 我认为没有办法绕过警告。您可能需要重写内部 URL....

标签: internet-explorer jquery https


【解决方案1】:

您无法绕过 IE 中的混合内容警告。如果远程资源可通过 HTTP 和 HTTPS 获得,您可以确保您的协议匹配 jQuery.load(location.protocol + '//someurl.com .someClass')


根据远程页面中混合内容的问题进行了更新:

jQuery.load整个 responseText 加载到 documentFragment 中,然后再拉出选择器指示的相应部分(请参阅jQuery 1.4.4 ajax.js)。整个远程页面被解析为 HTML 并且必须通过浏览器的安全流程;在许多方面,通过确保所有协议匹配和/或仅在您需要的情况下仅返回片段来确保响应“干净”更简单。

如果您不修改其他资源,这将更加健壮,您需要在远程资源被替换时将所有出现的 HTTP 替换为 HTTPS(反之亦然)仍然只是一个字符串。这是一个脆弱的 jQuery 插件作为这种技术的一个例子,大部分来自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);

用法:$('#your &gt; .selector').protocolModifyLoad(location.protocol + '//someurl.com', 'thisIsFragile!!!', '.someClass');

此函数省略了$.loadcallbackparams 参数,并添加了yesIKnowThisIsFragile 参数作为一个微妙的提醒。

【讨论】:

  • 如果你想确保从相同的协议加载资源,那么你可以指定“//domain.com/path/to/resource.js”作为路径,例如&lt;script src="//domain.com/path/to/resource.js"&gt;&lt;/script&gt;。如果您使用的是 https,那么浏览器将尝试从 https://domain.com 拉取该资源。
  • 该资源可作为 HTTP 和 HTTPS 使用,我通过 HTTPS 加载它。即使我为 .load() 提供了一个选择器,它应该会阻止浏览器实际解析文档并加载和执行链接的 JS 和 CSS,但 IE 似乎至少正在解析它并看到 HTTP 链接。
  • 协议相对 URL ("//example.com/example.js") 导致 IE7 和 IE8 下载文件两次:stevesouders.com/blog/2010/02/10/…
【解决方案2】:

如果安全页面加载任何非安全资源,它会抛出警告。解决它的唯一方法是从 https 加载所有内容。

即使是其他浏览器也应该在某处显示警告(可能在 FF 中地址的左侧?)

【讨论】:

  • Safari、Chrome 和 Firefox 都可以正常工作,并且不会因为添加到 URL 的选择器而引发错误——它们不会尝试解析整个文件。
  • 我敢打赌,他们不抛出错误的唯一原因是因为它们的默认性质是不抛出确认框,而 IE 是。我认为大多数不是 IE 的浏览器只是以另一种方式警告你。 FF3 在右下角显示一个带有感叹号的挂锁。如果像 IE 一样抛出确认,那么你很可能在 FF3 中遇到同样的问题。
  • 抱歉,在非 IE 浏览器中没有可见的迹象表明任何异常。
猜你喜欢
  • 2013-03-29
  • 2012-02-16
  • 1970-01-01
  • 2014-07-26
  • 2020-08-18
  • 2010-10-20
  • 2014-09-29
  • 1970-01-01
  • 2012-02-09
相关资源
最近更新 更多