如何检测跨地(CORS)误差与其他类型的错误,在Javascript的XMLHtt prequest() [英] How to Detect Cross Origin (CORS) Error vs. Other Types of Errors for XMLHttpRequest() in Javascript

查看:166
本文介绍了如何检测跨地(CORS)误差与其他类型的错误,在Javascript的XMLHtt prequest()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想,当一个XMLHtt prequest()失败,而不是一个坏的请求,以探测由一个跨起源错误。例如:

  ajaxObj =新XMLHtt prequest()
    ajaxObj.open(GET,URL,真正的);
    ajaxObj.send(空);
 

考虑4例网址​​:

案例1:网址是一个有效的地址,其中的访问控制,允许原产正确设置

  • 示例: http://192.168.8.35 在那里我有一个服务器访问控制 - 允许 - 产地:* 在头设置
  • 这是容易察觉的ajaxObj.readyState == 4和ajaxObj.status == 200

案例2:网址是无效的地址,在现有的服务器

  • 示例: http://xyz.google.com 的服务器的响应,但它不是一个有效的请求
  • 这导致ajaxObj.readyState == 4和ajaxObj.status == 0

案例3:网址是一个不存在的服务器IP地址

  • 示例: http://192.168.8.6 我的本地网络上哪里有什么回应
  • 这导致ajaxObj.readyState == 4和ajaxObj.status == 0

案例4:网址是一个有效的地址,其中的访问控制,允许原产地为设置

  • 示例: http://192.168.8.247 在那里我有一台服务器的 访问控制 - 可以让起源:在头* 设置
  • 这导致ajaxObj.readyState == 4和ajaxObj.status == 0

现在的问题是:如何做我区分案例4(访问控制 - 允许原产误差)和案例2及3

在案例四中,Chrome浏览器的调试控制台显示了错误:

XMLHtt prequest无法加载http://192.168.8.247/。原产地访问http://本地主机不会被允许访问控制 - 允许 - 原产地

如何让我的在Javascript知道错误?

我试图找到一些迹象表明在 ajaxObj ,但什么也没有,似乎比案例2和是不同的; 3。

下面是一个简单的测试,我使用的:

 <!DOCTYPE HTML PUBLIC -  // W3C // DTD XHTML 1.0过渡// ENhttp://www.w3.org/TR/xhtml1/DTD/ XHTML1-transitional.dtd>
< HTML的xmlns =htt​​p://www.w3.org/1999/xhtml>
< HEAD>
< META HTTP-当量=Content-Type的CONTENT =text / html的;字符集= UTF-8/>
<冠军> CORS测试< /标题>
<脚本类型=文/ JavaScript的>
功能PgBoot()
{
// doCORS(http://192.168.8.35); // 情况1
// doCORS(http://xyz.google.com); //案例2
    doCORS(http://192.168.8.6); //案例3
// doCORS(http://192.168.8.247); //案例4
}

功能doCORS(URL)
{
    。的document.getElementById(statusDiv)的innerHTML + =处理URL =+ URL +< BR>中;
    VAR ajaxObj =新XMLHtt prequest();
    ajaxObj.overrideMimeType(为text / xml');
    ajaxObj.onreadystatechange =功能()
    {
        VAR STAT =的document.getElementById(statusDiv);
        stat.innerHTML + =的readyState =+ ajaxObj.readyState;
        如果(ajaxObj.readyState == 4)
            stat.innerHTML + =,状态=+ ajaxObj.status;
        stat.innerHTML + =< BR>中;
    }
    ajaxObj.open(GET,URL,真正的);
    ajaxObj.send(空);
}
< / SCRIPT>
< /头>
<身体的onload =PgBoot()>
< D​​IV ID =statusDiv>< / DIV>
< /身体GT;
< / HTML>
 

使用Chrome结果:

 处理URL = HTTP://192.168.8.35
的readyState = 1
readyState的= 2
readyState的= 3
readyState的= 4,状态= 200
 


 处理URL = HTTP://xyz.google.com
的readyState = 1
readyState的= 4,状态= 0
 


 处理URL = HTTP://192.168.8.6
的readyState = 1
readyState的= 4,状态= 0
 


 处理URL = HTTP://192.168.8.247
的readyState = 1
readyState的= 4,状态= 0
 

解决方案

没有,有没有办法分辨出来,根据W3C规范。

下面是如何的CORS规范规定的简单的跨域请求过程:

  

应用提出申请步骤和观察,同时提出要求如下申请的规则。

     

如果手动重定向标志没有设置,响应具有301 HTTP状态code,302,303,307,或308:的应用重定向步骤

     

如果最终用户取消请求:的应用中止步骤

     

如果出现网络错误:如果DNS错误,TLS协商失败,或其他类型的网络错误,对应用的网络错误步骤。不要求任何最终用户交互的......

     

否则:的执行资源共享检查。 如果返回失败,应用网络错误步骤

在任何一个失败的网络连接或发生故障的CORS交流,网络错误步骤的情况下< /一>施加,所以字面上没有办法在两种情况之间进行区分。

为什么呢?一个好处是,它prevents攻击者从检查一个局域网的网络拓扑。例如,一个恶意网页脚本可以通过要求其HTTP接口找到你的路由器的IP地址,因此能学到很多关于你的网络拓扑结构(例如,有多大你的私有IP块, / 8 / 16 )。由于您的路由器不(或不应该)发送CORS头文件,脚本学习绝对没有。

I'm trying to detect when an XMLHttpRequest() fails due to a Cross Origin Error as opposed to a bad request. For example:

    ajaxObj=new XMLHttpRequest()
    ajaxObj.open("GET", url, true); 
    ajaxObj.send(null);

Consider 4 cases for url:

Case 1: url is a valid address where access-control-allow-origin is properly set

  • Example: http://192.168.8.35 where I have a server with Access-Control-Allow-Origin: * set in the header
  • This is easy to detect as ajaxObj.readyState==4 and ajaxObj.status==200

Case 2: url is an invalid address at an existing server

  • Example: http://xyz.google.com where the server responds but it is not a valid request
  • This results in ajaxObj.readyState==4 and ajaxObj.status==0

Case 3: url is to a non-existing server ip address

  • Example: http://192.168.8.6 on my local network where there is nothing to respond
  • This results in ajaxObj.readyState==4 and ajaxObj.status==0

Case 4: url is a valid address where access-control-allow-origin is NOT set

  • Example: http://192.168.8.247 where I have a server without Access-Control-Allow-Origin: * set in the header
  • This results in ajaxObj.readyState==4 and ajaxObj.status==0

The problem is: How do I differentiate Case 4 (access-control-allow-origin error) and Cases 2&3?

In Case 4, the Chrome debug console shows the error:

XMLHttpRequest cannot load http://192.168.8.247/. Origin http://localhost is not allowed by Access-Control-Allow-Origin.

How do I make that error known in Javascript?

I tried to find some indication in ajaxObj but nothing there seems to be different compared to Case 2&3.

Here is a simple test I used:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>CORS Test</title>
<script type="text/javascript">
function PgBoot()
{
//  doCORS("http://192.168.8.35");   // Case 1
//  doCORS("http://xyz.google.com"); // Case 2
    doCORS("http://192.168.8.6");    // Case 3
//  doCORS("http://192.168.8.247");  // Case 4
}

function doCORS(url)
{
    document.getElementById("statusDiv").innerHTML+="Processing url="+url+"<br>";
    var ajaxObj=new XMLHttpRequest();
    ajaxObj.overrideMimeType('text/xml');
    ajaxObj.onreadystatechange = function()
    {
        var stat=document.getElementById("statusDiv");
        stat.innerHTML+="readyState="+ajaxObj.readyState;
        if(ajaxObj.readyState==4)
            stat.innerHTML+=", status="+ajaxObj.status;
        stat.innerHTML+="<br>";
    }
    ajaxObj.open("GET", url, true); 
    ajaxObj.send(null);
}
</script>
</head>
<body onload="PgBoot()">
<div id="statusDiv"></div>
</body>
</html>

Results using Chrome:

Processing url=http://192.168.8.35
readyState=1
readyState=2
readyState=3
readyState=4, status=200


Processing url=http://xyz.google.com
readyState=1
readyState=4, status=0


Processing url=http://192.168.8.6
readyState=1
readyState=4, status=0


Processing url=http://192.168.8.247
readyState=1
readyState=4, status=0

解决方案

No, there is no way to tell the difference, according the W3C Spec.

Here's how the CORS specification specifies the simple cross-origin request procedure:

Apply the make a request steps and observe the request rules below while making the request.

If the manual redirect flag is unset and the response has an HTTP status code of 301, 302, 303, 307, or 308: Apply the redirect steps.

If the end user cancels the request: Apply the abort steps.

If there is a network error: In case of DNS errors, TLS negotiation failure, or other type of network errors, apply the network error steps. Do not request any kind of end user interaction...

Otherwise: Perform a resource sharing check. If it returns fail, apply the network error steps...

In the case of either a failed network connection or a failed CORS exchange, the network error steps are applied, so there is literally no way to distinguish between the two cases.

Why? One benefit is that it prevents an attacker from inspecting the network topology of a LAN. For example, a malicious Web page script could find the IP address of your router by requesting its HTTP interface and therefore learn a few things about your network topology (e.g., how big your private IP block is, /8 or /16). Since your router doesn't (or shouldn't) send CORS headers, the script learns absolutely nothing.

这篇关于如何检测跨地(CORS)误差与其他类型的错误,在Javascript的XMLHtt prequest()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆