使用 IE11 的 CORS 请求

Posted

技术标签:

【中文标题】使用 IE11 的 CORS 请求【英文标题】:CORS request with IE11 【发布时间】:2013-12-10 12:15:57 【问题描述】:

我有一个 CORS(跨源资源共享)请求,从我的登录页面到应用程序站点,位于不同的 URL。我有一个简单的页面,我 ping 以确定用户是否已经登录,如果是,则重定向它们。否则我会显示一个登录页面。我使用 jQuery。

这在 safari、chrome、firefox 中效果很好......而不是 IE(自然)。根据 MS 的说法,IE 10 及更高版本应该支持CORS requests with withCredentials

我正在使用 jquery-2.0.3.min.js

任何想法为什么这在 IE11 中不起作用?

编辑:它看起来好像是部分工作,因为它现在返回值 "id":false。每次都会发生这种情况,这意味着服务器永远不会获得凭据。我也在发布我的 is_logged_in 页面,我正在使用代码点火器框架。

编辑:在 IE 的安全设置下启用“允许跨域数据源”后,我不再收到任何错误消息。

我收到的确切错误是:

SEC7118:http://mysite.net/guest/is_logged_in 的 XMLHttpRequest 需要跨域资源共享 (CORS)。

$.ajax(
url: 'http://mysite.net/guest/is_logged_in',
type: 'POST',
crossDomain: true,
xhrFields: 
       withCredentials: true
  ,

dataType: 'json',
success: function(data) 

    if(data.id) 
        window.location.replace("http://mysite.net");
    

);

public function is_logged_in()

    $allowed = array(
        'http://mysite.net',
        'http://www.mysite.net',
        'http://www.mysite.com',
    );

    $url = $_SERVER['HTTP_REFERER'];
    $url = substr($url, 0, strpos($url, '/', 8));
    if(isset($_SERVER['HTTP_ORIGIN']))
    
        if(in_array($_SERVER['HTTP_ORIGIN'], $allowed))
        
            $this->output->set_header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
        
    
    else
    
        if(in_array($url, $allowed))
        
            $this->output->set_header('Access-Control-Allow-Origin: ' . $url);
        
    


    $this->output->set_header('Access-Control-Allow-Headers: X-Requested-With');
    $this->output->set_header('Access-Control-Allow-Credentials: true');
    $this->output->set_header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");


    //TODO: Try to detect if this is an ajax request, and disallow it if not.

    $data = new stdClass();
    $this->load->library("ion_auth");
    if($this->ion_auth->logged_in())
    
        $data->name = $this->ion_auth->user()->row()->first_name;
        $data->id = $this->ion_auth->get_user_id();
     else 
        $data->id = false;
    

    $this->output->set_output(json_encode($data));


提前致谢

【问题讨论】:

您是否有机会在 Internet 中设置了“杂项 -> 跨域访问数据源”设置 -> 安全选项设置为禁用? 你成功重定向的事实让我想知道你是否需要 ajax。 事实上,它被设置为“禁用”。我开启了,还是不行,现在也没有报错了。 您的 IE 缓存中是否有这个 js 的旧版本(在添加“withCredentials”设置之前)(IE 喜欢缓存。喜欢它)?这里只是猜测。 IE 也喜欢缓存来自 ajax 请求的数据。确保使用类似:$.ajaxSetup(cache: false)。 它不再给你一个错误的事实表明 ajax 是成功的(或者至少服务器响应并且脚本有凭据可以继续)。服务器输出的响应是什么?编辑:也许是location.replace 的事情?首先尝试检查代码是否仅使用 window.alert(data) 进入成功块 【参考方案1】:

将“跨域访问数据源”的设置更改为启用会关闭 IE 中的跨域检查,并且非常不安全。相反,您需要确保目标第 3 方资源发送 valid P3P policy,表明它没有对用户的隐私造成可怕的影响。

【讨论】:

我研究了 P3P,但决定放弃它,因为它并没有真正使用。来自*** > P3P 由万维网联盟 (W3C) 开发,并于 2002 年 4 月 16 日正式推荐。此后不久开发停止,P3P 的实现很少。 Microsoft Internet Explorer 是唯一支持 P3P 的主流浏览器 你:“为什么我的代码在 IE 中不起作用?”我:“因为 IE 需要 P3P。”你:“但是 P3P 并没有真正被使用,除了在 IE 中。”我:“……” 这是表达我立场的一种非常优雅的方式(:是的,如果这是一个更关键的功能,我将实施 P3P 策略。我会给你答案,因为你在技术上正确,这是最好的正确。 我在响应头中添加了 P3P,但还是不行。我只能更改“跨域访问数据源”以使其工作! 在 *** 上提问的正确方法是点击页面右上角的蓝色“提问”按钮。您的问题是:“我如何允许使用 CORS 跨域访问数据?”这可能已经被问过很多次了。【参考方案2】:

发现问题。

我遇到了类似的问题(一般使用 CORS,而不是专门使用 GWT)。 原来是浏览器设置屏蔽了第三方 cookie(IE10 > Internet 选项 > 隐私 > 高级 > 第三方 Cookies > 接受)。为了解决这个问题,我检查了“覆盖自动 cookie 处理”、​​“接受”(第三方 Cookie)和“始终允许 会话 cookie。”

安德鲁在这里回答了这个问题:CORS doesn't work with cookies in IE10

编辑:(现在我知道要搜索什么)如果其他人遇到这个问题,这个问题也可能会产生一些帮助。 Internet Explorer 10 is ignoring XMLHttpRequest 'xhr.withCredentials = true'

【讨论】:

是的,这也为我解决了一个类似的问题。【参考方案3】:

我们遇到的问题是,除了所有其他浏览器,IE11 都会发送Access-Control-Request-Headers: accept 请求,因此必须将“accept”添加到 allowedHeaders cors 配置中,因为它似乎不是默认 spring cors 的一部分配置。

【讨论】:

在我的情况下它发送Access-Control-Request-Headers: content-type, accept 这个建议帮助我解决了 AWS API Gateway v2 (httpapi) 的 IE11 CORS 问题。在 CORS 配置中,我们的 Access-Control-Allow-Headers 白名单现在是:x-apigateway-header、authorization、content-type、accept。也可以与 Axios Vue 库一起使用(看到另一个答案提到他们无法让它工作)。谢谢!【参考方案4】:

IE10 要求服务器返回有效的 P3P 策略以及跨域请求的 CORS 标头。这是用于从服务器返回 P3P 标头的示例 php 代码。

  $szOrigin = $_SERVER['HTTP_ORIGIN'];
  if ($szOrigin != null)
  
        header("Access-Control-Allow-Origin: $szOrigin");
        header("Access-Control-Allow-Credentials: true");
        header("P3P: CP=\"ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI\"");
  

【讨论】:

【参考方案5】:

经过大量挖掘,我发现我使用 ajax ping 的页面位于 Internet 区域,而我当前的页面位于 Intranet 区域。

IE 11 为 Internet 站点启用了“保护模式”,当启用此功能时,cookie 不会发送到我正在 ping 的站点,即使它们属于该域。

将页面添加到受信任的站点,或禁用“保护模式”即可解决问题。

请注意,即使启用了“保护模式”,当两个站点都在 Internet 区域中时,也不会发生此问题。

【讨论】:

【参考方案6】:

我遇到了类似的问题,发现 axios 或 jquery 都不能与 Internet Explorer 和 preflight/CORS 问题一起使用。只有好的旧 XMLhttpRequest 有效。因为在纯 XMLhttpRequest 中我们可以这样做:

if (xhttp.readyState == 4 && xhttp.status == 200)

似乎 axios 和 jquery 考虑了状态而不是 readyState - 它们以某种方式解释存在 cors 问题 - 在 IE 中达到 readyState == 4 需要一些滴答声。

【讨论】:

以上是关于使用 IE11 的 CORS 请求的主要内容,如果未能解决你的问题,请参考以下文章

IE 11 上 CORS 预检请求的奇怪问题失败

CORS 请求在 Firefox 中中止,而不是在 Chrome 或 IE 中

来自 IE 或 Firefox 的 CORS 请求中没有 Referer 标头

IE 11 跨域请求

在 Angularjs 中的 IE10+ 中访问被拒绝 CORs 请求,需要跨源资源共享错误(信息?)

IE11 CORS 拒绝 https 上的 OPTIONS