使用 XMLHttpRequest 时没有启用 CORs?

Posted

技术标签:

【中文标题】使用 XMLHttpRequest 时没有启用 CORs?【英文标题】:CORs does not get enabled when using XMLHttpRequest? 【发布时间】:2015-05-06 07:00:40 【问题描述】:

我花了几个小时试图从不同的域访问资源。

http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/ 在其他 SO 帖子中被引用指出,通过在支持 CORS 的浏览器中简单地使用 XMLHttpRequest,应该启用 CORS 策略。但是我仍然得到 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.nczonline.net/. This can be fixed by moving the resource to the same domain or enabling CORS.

在 Firefox 34 中使用它时,根据 http://caniuse.com/#feat=cors 应该就足够了。

我正在尝试来自http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/ 的一个简单示例

<script type="text/javascript">
    function log(msg)
        var output = $('#output');
        output.text(output.text() + " | " + msg);
        console.log(msg);
    

    function createCORSRequest(method, url)
        var xhr = new XMLHttpRequest();
        if ("withCredentials" in xhr)
            xhr.open(method, url, true);

            log("'withCredentials' exist in xhr");
         else if (typeof XDomainRequest != "undefined")
            xhr = new XDomainRequest();
            xhr.open(method, url);

            log("XDomainRequest is being used");
         else 
            xhr = null;

            log("xhr is null");
        
        return xhr;
    

    function main()
        log("Attempting to make CORS request");

        var request = createCORSRequest("get", "https://www.nczonline.net/");
        if (request)
            request.onload = function()
                log("LOADED!");
            ;

            request.send();
        
    

    $(window).load(function()
        main();
    );
</script>

我得到以下输出:

Attempting to make CORS request 'withCredentials' exist in xhr Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.nczonline.net/. This can be fixed by moving the resource to the same domain or enabling CORS.

在小提琴https://jsfiddle.net/zf8ydb9v/ 上尝试它会得到相同的结果。是否有另一个杠杆需要打开才能使用 XMLHttpRequest 使用 CORS bBesides?

【问题讨论】:

【参考方案1】:

same origin policy(防止发出 CORS 请求)是为了您的安全,而不是服务器的安全:它可以防止恶意脚本使用您的 cookie 访问您在其他服务器上的数据。 因此,如果您愿意,您仍然可以在您的浏览器上禁用它,风险自负。

在 Chrome/Chromium 中,如果您想禁用同源策略,可以使用 --disable-web-security 选项启动它:

chromium-browser --disable-web-security

无论如何,如果您希望它为您的用户工作,如果他们没有在浏览器中禁用此安全检查(如果不进行测试,则不鼓励这样做),他们将无法发出 CORS 请求。

如其他答案中所述,如果某些服务器认为此类请求对其用户有用且无害,则它们可以故意允许此类请求,并且他们可以使用访问控制标头来做到这一点。

此外,如果您仍想找到一种向用户提供此类功能的方法,您可以制作一个 Chrome 扩展程序,which is not bound to the same origin policy。

一个常见的解决方案是让跨源请求服务器端,将结果返回给您的应用程序。您应该小心编码:将 url 传递给服务器很容易引起服务器端软件的安全问题。但是,如果您每次都必须获取相同的 url,您可以在服务器端对其进行硬编码,在 php 中看起来像这样:

<?php
    echo file_get_contents("http://your_cross_request/");
?>

然后向该页面发出 ajax 请求(将来自同一来源)将返回远程 url 的内容。

【讨论】:

这使得 CORS 看起来对生产毫无用处,因为我们不能期望用户在禁用安全策略的情况下启动他们的浏览器 这正是重点。 CORS 在浏览器中默认禁用,因为它们会导致重要的安全问题,因此在生产中依赖它们是不可能的,chrome 扩展例外。 @NickolayKondratyev:这个答案有点误导。 CORS 与浏览器安全级别无关。它是一种协议,使服务器能够告诉浏览器可以使用 XHR 获取数据,而不是因为它是跨源的而阻止它。要启用 CORS,您需要修改从中获取数据的服务器(并非总是可能),并使其发送 CORS 标头,从而允许您的站点获取其数据。此答案中的所有其他内容都是关于同源政策,这是一个相关主题,但 不是 CORS。 现在,当我按照@Paul S 的建议尝试用https://developer.mozilla.org/en-US/(来自“nczonline.net/")替换我的示例代码时,我更加困惑。我没有收到CORS错误。但我做到了没有在禁用安全的情况下启动我的浏览器 我只是像往常一样启动了 Firefox。【参考方案2】:

CORS headers 可以在服务器发送给您的请求响应中找到。如果请求的页面没有发送标头,那么无论您在股票浏览器中对请求做了什么,都会出现安全错误

相关的CORS头看起来像这样,最后一个是最重要的

Access-Control-Allow-Credentials: false
Access-Control-Allow-Methods: GET
Access-Control-Allow-Origin: *

我尝试打开 "nczonline.net",当我查看响应头时,我没有看到任何这些,因此服务器未配置为允许以这种方式加载

如果您是该网站的管理员,您可能需要考虑在您的回复中添加所需的标头,可能会具体说明允许的来源,而不是使用通配符

如果您只是想演示您的代码并想与第三方一起尝试,请加载一个发送这些标头的页面,例如developer.mozilla.org

【讨论】:

拥有Access-Control-Allow-Origin 的通配符会使合规的用户代理拒绝在预检请求之后向请求提供任何凭据(它会获得上述标头作为响应)。来源:w3.org/TR/cors/#resource-requests

以上是关于使用 XMLHttpRequest 时没有启用 CORs?的主要内容,如果未能解决你的问题,请参考以下文章

XMLHttpRequest 错误 - Flutter Web 中的 CORS 问题(C#)

为啥我使用xmlhttprequest抓取数据时主键跳转量大?

Firefox 设置启用跨域 Ajax 请求

使用 Spring Framework 为 OPTIONS 请求启用 CORS

如何为 Google Places API 启用 CORS

错误:使用天气 API 时出现 XMLHttpRequest 错误