CORS https对localhost的访问权限适用于Chrome,但不适用于Firefox

时间:2014-09-01 17:27:58

标签: javascript firefox ssl google-apps-script cors

我在firefox和IE上遇到了一个CORS问题,而Chrome似乎也处理了同样的情况。

我需要从浏览器中运行的Web应用程序访问本地mongoose服务器。我从我的网络应用程序发送XMLHTTP请求,这是一个Google App脚本 - HTMLService(从https://script.google.com提供)到运行在localhost上运行的mongoose服务器的本地客户端 - 127.0.0.1:1234。 XMLHTTP请求被发送到

https://localhost:1234/ping

通过HTTPS(GET)。服务器应以“PING_OK”消息作为纯文本进行响应。 我们还将浏览器指向

https://localhost:1234/ping

让我们的测试证书被接受为可靠来源。 完成上述步骤后,Chrome浏览器可以访问本地mongoose服务器,但Firefox失败并显示消息“NS_ERROR_DOM_BAD_URI:访问限制URI被拒绝”(IE也失败)

file:///c:test.html投放时,测试html页面也可以访问

https://localhost:1234/ping

通过Firefox和Chrome。

这是html中的javascript:

  var xmlhttp;
  if (window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
  }
  else {
    // code for IE6, IE5
    xmlhttp=new ActiveXObject('Microsoft.XMLHTTP');
  }


  //  set the onreadystatechange callback
  xmlhttp.onreadystatechange = function() {
    var xStatus = ['UNSENT','OPENED','HEADERS_RECEIVED','LOADING','DONE'];
    if (xmlhttp.readyState==4 && xmlhttp.status==200) {
        var response =  xmlhttp.responseText;
        console.log('Response: '+response);
    } else if((xmlhttp.readyState>0) && (xmlhttp.readyState<4)){
        console.log('state='+ xStatus[xmlhttp.readyState]+', status='+ xmlhttp.statusText);
    } else {
        console.log('state='+ xStatus[xmlhttp.readyState]+', status='+ xmlhttp.statusText);
      }
  }


  //  set the timeout value and the ontimeout callback

  xmlhttp.timeout = 30000;
  xmlhttp.ontimeout = function() {
       console.log('XHR timed out');
  }

  var url = 'https://localhost:1234/ping';
  var params = '';


  xmlhttp.open('POST', url, true);
  xmlhttp.send(params);

服务器证书是使用openSSL为“”OTHER“(Mongoose-c ++)生成的测试证书,并使用以下选项进行设置。

以下是本地计算机上mongoose服务器端的代码。

void FakeWebServer::handlePingRequest(struct mg_connection *conn) {

/// Set headers
mg_send_header(conn, "Access-Control-Allow-Origin", "*");
mg_send_header(conn, "Access-Control-Allow-Methods", "POST, GET, OPTIONS");
mg_send_header(conn, "Access-Control-Allow-Headers", "X-PINGOTHER");
mg_send_header(conn, "Access-Control-Max-Age", "1728000");

mg_send_header(conn, "Content-Type", "text/plain");

/// Send Fake Message
std::string msg = "PING_OK";
mg_send_data(conn, msg.c_str(), strlen(msg.c_str()));
}

以上代码通过谷歌应用程序脚本部署为webapp时很乐意在Chrome中运行,但Firefox失败并显示“NS_ERROR_DOM_BAD_URI:访问限制URI被拒绝”

我对javascript编程比较陌生,我不确定这是否是我面临的SSL相关问题或者是CORS ...

1)我在两端的这种ssl访问中是否缺少任何其他参数或配置?

2)另外,为什么从file:/// * html提供的页面能够访问

https://localhost:1234

通过CORS,而完全相同的html从

提供
https://script.google.com

在Firefox(和IE)上失败。

非常感谢任何解决此问题的指示和建议。

1 个答案:

答案 0 :(得分:0)

我遇到类似的问题,Chrome和IE工作正常,但是当使用Dojo从JavaScript调用WebAPI时,Firefox失败了。事实证明,Firefox发送的“接受”标题是不同的,我的API不支持。 Chrome发送此信息:

Accept: */*

Firefox发送此信息:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

因此,Firefox收到500错误。我通过覆盖JavaScript调用中的标头来解决问题。这是使用Dojo + TypeScript的代码,但您应该能够在您的环境中执行类似的操作。

    var d = new Deferred();
    var token = this._getToken();
    var options = {
        method: 'GET',
        handleAs: 'json',
        headers: {
            'Accept': '*/*',
            'Authorization': 'Bearer ' + token
        }
    };
    request<Object>(url, options).then(
        function (result) {
            d.resolve(result);
        },
        function (err) {
            d.reject(err, true);
        }
    );
    return d.promise;

这只是一种解决方法。真正的问题是,由于Firefox的“Accept”标头,WebAPI试图以XML格式返回响应。我从来没有将我的数据传输对象设置为XML格式,因此WebAPI引发了500错误。因此,作为最终解决方案,我从WebAPI中删除了XMLFormatter,如下所示:

config.Formatters.Remove(config.Formatters.XmlFormatter);

更持久的解决方案是使WebAPI处理XML,但我现在不这样做。