Internet Explorer 中跨站点请求的访问控制

Posted

技术标签:

【中文标题】Internet Explorer 中跨站点请求的访问控制【英文标题】:Access control for cross site requests in Internet Explorer 【发布时间】:2011-01-03 22:04:56 【问题描述】:

我正在尝试从多个域向一个将处理请求的域进行 AJAX 调用。通过在处理服务器上设置标头,在 Firefox 和 Chrome 中启用跨域很容易:

header("Access-Control-Allow-Origin: *");

但这无助于在 Internet Explorer 中启用它。当我尝试时:

httpreq.send('');

它因错误访问被拒绝而停止。

如何在 Internet Explorer 中启用此功能?

【问题讨论】:

IE 10 工作正常,IE8/9 有限制。见caniuse.com/#search=cors IE9对CORS支持的具体限制是什么? 【参考方案1】:

您是否尝试过启用跨域访问数据源

【讨论】:

这对于在 localhost:8080 上测试网站很有用 像魅力一样工作。在 localhost +1 上测试真的很有用【参考方案2】:

对于 Internet Explorer 8,您需要对 FF3 执行类似操作,即使用“Access-Control-Allow-Origin”标头并使用 XDomainRequest 对象而不是 XMLHttpRequest。 IE8 的所有内容都在这里详细说明: http://msdn.microsoft.com/en-us/library/dd573303%28VS.85%29.aspx

旧版本的 IE 不支持跨站点访问控制也不支持 XDomainRequest 对象。 然而这还没有结束,你可以使用 IFrame 技巧,例如,创建一个不可见的 IFrame 来调用你的函数,如下所述: http://softwareas.com/cross-domain-communication-with-iframes

【讨论】:

【参考方案3】:

自从我第一次在 IE7 及更高版本中发布我的 CORS 解决方案以来,发生了很大变化。首先,jQuery 属性 $.support.cors 默认为 true,.NET 框架 4.0 及更高版本不再支持在 3.5.1 及更低版本中实现的 CORS。使用 ASP.NET 4.0 编写 Web 服务时,我安装了 Thinktecture.IdentityModel,它可作为 NuGet 包使用。然后,在 Global.asax 文件的 Application_Start 方法中,添加:

void Application_Start(object sender, EventArgs e) 
 
    Thinktecture.IdentityModel.Http.Cors.IIS.UrlBasedCorsConfiguration.Configuration
        .ForResources("*")
        .ForOrigins("http://localhost:80, http://mydomain")
        .AllowAll()
        .AllowMethods("GET", "POST");

现在在 system.webServer 中添加 httpProtocol 元素:

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type, Accept, X-Requested-With, X-File-Name" />
    <add name="Access-Control-Allow-Methods" value="GET, POST" />
  </customHeaders>
</httpProtocol>

我的 $.ajax 调用现在是:

$.ajax(
    url: serviceUrl, 
    data: JSON.stringify(postData),
    type: "POST",
    cache: false,
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: onSuccess,
    error: onError
);

【讨论】:

第一次发布这个问题时,IE 6 和 7 仍然很常见,而且它们根本不支持 CORS。我不相信$.support.cors 那时也没有实施。很高兴知道情况有所改善! from api.jquery.com/jQuery.support "...cors 等于 true 如果浏览器可以创建 XMLHttpRequest 对象并且该 XMLHttpRequest 对象具有 withCredentials 属性。在不支持的环境中启用跨域请求支持 cors 但确实允许跨域 XHR 请求(Windows 小工具等),设置 $.support.cors = true;..."。我已经在 IE7、IE8 和 IE9 中验证了此功能。 救命稻草。感谢您发布此内容。 这很好,但在 IE8 中不起作用。这个github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest 非常有用,它适用于所有浏览器,包括 IE8(尚未在 IE 7 中测试)感谢@gbakernet 感谢 Srikanth 的回复。该解决方案在 IE8 中对我们的用户有效。可能还有其他变量会影响您的实施。自发布此解决方案以来,发生了很大变化。 $.support.cors 在所有更高版本的 jQuery 中默认为 true,并且此方法不再适用于 .Net 框架 4 及更高版本。您现在必须包含一个库,例如 Thinktecture.IdentityModel.dll,以便 CORS 与 .Net 服务一起使用。必须在 Global.asax 方法 Application_Start 中启用 CORS【参考方案4】:

我让 IE8 和 9 只使用 jQuery $.ajax(jQuery 版本 1.7.2)

jQuery.support.cors = true;
jQuery(function() 
$.ajax(
    crossDomain : true,
    dataType: 'html',
    //...
    );
);

【讨论】:

【参考方案5】:

只是添加到 Eric 的答案,对于旧版本的 IE,您可以使用 Jquery 1.4.2 的 $.ajax 方法,默认情况下允许跨域请求,或者对于跨域 JSON,您可以使用

jQuery.getJSON(String url, Map data, Function callback) 返回 XMLHttpRequest

Jquery 文档节选。

“jQuery 现在原生支持 JSONP - 如果您尝试从远程 URL 加载 JSON(通过 $.getJSON 或 $.ajax),那么将为服务器提供额外的回调来解释。”

【讨论】:

澄清一下,这个only适用于jsonp请求。 jQuery 不提供对 XDomainRequest 的支持,以及需要 jQuery 1.5 或更高版本的解决方法:bugs.jquery.com/ticket/8283【参考方案6】:

我不相信您可以直接在 Internet Explorer 中执行此操作。您有两种选择:

在您控制的可以转发 Ajax 请求的服务器上设置代理转发脚本。确保它只转发到您需要的适当目的地,以免您变成匿名中继。

使用document.domain 技巧。基本上,您需要创建一组iframes,一个用于您需要进行Ajax 调用的每个服务器。在每个iframe 中,将document.domain 属性设置为与您发送Ajax 请求 所需的域完全匹配。至于如何填充必要的数据,请在设置 document.domain 之前使用 DOM 操作。请注意,此技巧要求目标服务器位于原始服务器的子域中。 this article 中的更多内容,并附有示例。

【讨论】:

抱歉回复晚了。我已经用服务器上的代理脚本完成了。

以上是关于Internet Explorer 中跨站点请求的访问控制的主要内容,如果未能解决你的问题,请参考以下文章

Internet Explorer 11 通过元标记禁用“在兼容性视图中显示 Intranet 站点”不起作用

检测当前 Internet Explorer 安全区域

Internet Explorer 取消 ajax 请求

Internet Explorer 中允许的 Ajax 跨域请求

ExtJS Ajax 请求超时对 Internet Explorer 没有影响

Internet Explorer 9 AJAX 请求上没有会话 Cookie