跨域资源共享(CORS)概念

问题描述 投票:15回答:3

我对跨域JavaScript这个概念有疑问。

有服务器(ex amazon.com),只有选定的域可以使用他们的网络服务。所以当然,如果我尝试使用他们的服务,从我的本地,我不能。我在控制台上得到了这个

跨源请求已阻止:同源策略禁止在http://football20.myfantasyleague.com/2014/export?TYPE=rosters&L=52761&W=&JSON=0上读取远程资源。这可以通过将资源移动到同一域或启用CORS来解决。

PS:我也使用了jquery跨域方式,但没有用。

但是,如果使用亚马逊的web服务,那些选定的域之一的域名有一个JavaScript,如果我们在html中包含它,它就可以工作。

<script src="http://example.com"></script>

他们有一种方法来获得Ajax的响应。

我的问题是:

  1. 当我们从互联网网址引用JavaScript文件时会发生什么。我们的机器上是否有本地副本?
  2. 是否创建了httpRequest,将请求源作为我的域或xyz。
javascript jquery ajax cors
3个回答
38
投票

重要提示:如果另一端的服务器没有启用它,那么在客户端代码中你无法做任何事情来允许跨源的ajax请求。

在回答你的问题之前,我先给你一个背景:

Same-Origin Security Policy

简而言之,同源安全策略可确保来自一个源的脚本可能无法从其他来源获取内容。现在向你解释一下原产地的概念,让我引用Wikipedia article of Same-Origin Security Policy的一部分:

下表概述了针对URL“http://www.example.com/dir/page.html”进行检查的典型结果。

Compared URL                                             Outcome  Reason
-------------------------------------------------------  -------  ----------------------
http://www.example.com/dir/page2.html                    Success  Same protocol and host
http://www.example.com/dir2/other.html                   Success  Same protocol and host
http://username:[email protected]/dir2/other.html Success  Same protocol and host
http://www.example.com:81/dir/other.html                 Failure  Same protocol and host but different port
https://www.example.com/dir/other.html                   Failure  Different protocol
http://en.example.com/dir/other.html                     Failure  Different host
http://example.com/dir/other.html                        Failure  Different host (exact match required)
http://v2.www.example.com/dir/other.html                 Failure  Different host (exact match required)
http://www.example.com:80/dir/other.html                 Depends  Port explicit. Depends on implementation in browser.

与其他浏览器不同,Internet Explorer在原点计算中不包括端口,使用安全区域。

因此,例如,您的JavaScript无法从源自其服务器的Web服务器(也称为发出HTTP请求)下载任何内容。这正是您无法向其他域创建XmlHttpRequests(aka AJAX)的原因。


CORS是另一端的服务器(不是浏览器中的客户端代码)可以relax the same-origin policy的一种方式。

关于Cross Origin Resource Sharing (CORS)的简化描述。

CORS标准通过添加新的HTTP标头来工作,这些标头允许服务器将资源提供给允许的源域。浏览器支持这些标头并尊重它们建立的限制。

示例:假设您的站点是http://my-cool-site.com,并且您在域http://third-party-site.com上有第三方API,您可以通过AJAX访问它。

我们假设您的服务器my-cool-site.com的页面向third-party-site.com发出请求。通常,用户浏览器会根据Same-Origin Security Policy拒绝对您自己的域/子域以外的任何其他站点的AJAX调用。但是如果浏览器和第三方服务器支持CORS,则会发生以下情况:

  • 浏览器将发送和Origin HTTP标头发送到third-party-site.com Origin: http://my-cool-site.com
  • 如果第三方服务器接受来自您域的请求,它将使用Access-Control-Allow-Origin HTTP标头进行响应: Access-Control-Allow-Origin: http://my-cool-site.com
  • 要允许所有域,第三方服务器可以发送此标头: Access-Control-Allow-Origin: *
  • 如果您的站点不被允许,浏览器将抛出错误。

如果客户端具有相当现代的browsers that support CORS,以及您的第三方服务器supports CORS,CORS对您也很有用。

在一些过时的浏览器(例如IE8)中,您必须使用特定于Microsoft的XDomainRequest对象而不是XMLHttpRequest来进行与CORS一起正常工作的调用;现在已经过时了,所有现代浏览器(包括来自微软)都在XMLHttpRequest处理CORS。但是如果你需要支持过时的浏览器,this page会描述它:

要制作CORS请求,您只需在Firefox 3.5 +中使用XMLHttpRequest,在IE8 +中使用Safari 4+以及Chrome和XDomainRequest对象。使用XMLHttpRequest对象时,如果浏览器发现您正在尝试发出跨域请求,它将无缝触发CORS行为。

这是一个javascript函数,可以帮助您创建跨浏览器CORS对象。

function createCORSRequest(method, url){
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr){
        // XHR has 'withCredentials' property only if it supports CORS
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined"){ // if IE use XDR
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}

同样,这只是过时的浏览器所必需的。


上述原因导致您无法使用脚本中的Amazon Web服务。亚马逊服务器只允许将其JavaScript文件下载到从选定域提供的页面。

要回答您编号的问题:

  1. 如果文件位于同一源,则浏览器将下载该文件。 如果它不在同一个源中,则在CORS请求成功时将下载该文件。 否则,下载脚本将失败。 如果下载成功,则JavaScript文件的内容将加载到浏览器的内存中,解释并执行。
  2. 请参阅有关CORS的说明以了解。

4
投票

CORS是必须在服务器上修改的设置。它允许外部域请求网页上的资源。简单地在客户端上更改代码不会改变CORS的功能。

您可以从“脚本”标记中访问页面的原因是,标记的处理方式与跨源请求的所有其他数据的处理方式不同。在过去,您可以使用JSONP将CORS“破解”到您的系统上,JSONP将JSON数据存储在HTML标记内。

要在Apache中启用CORS:

首先通过输入找到你的httpd.conf

ps -ef | grep apache

这将为您提供Apache的位置。找到该类型后:

 <apache-location> -V

这将返回你的httpd.conf的确切位置,如:

 -D SERVER_CONFIG_FILE="/etc/apache2/apache2.conf"

现在你需要转到httpd.conf并输入“/”来搜索<directory>。一旦找到标签,就在它输入后:

Header set Access-Control-Allow-Origin "*"

运行以下命令保存文件并确认语法正确:

apachectl -t

如果检出,请运行graceful restart命令:

apachectl -k graceful

服务器重新启动后,现在可以通过外部脚本访问您的文件。

如果由于错误而无法保存配置,请尝试退出编辑器并键入:

sudo chmod 755 httpd.conf

这使得所有者可以完全访问配置文件,但其他人只能读取执行它(http://en.wikipedia.org/wiki/Chmod)。

要测试这些更改,请在外部服务器上创建一个新的index.html文件,并使用以下内容加载它:

<!doctype html>
<html>
    <head>
    <title>TEST</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js"></script>
    <script src="http://code.jquery.com/jquery-1.11.1.js"></script>
    <!-- Insert Scripts & CSS Here -->
    <link rel="stylesheet" type="text/css" href="http://d1e24pw9mnwsl8.cloudfront.net/c/bootstrap/css/bootstrap.min.css">
    </head>

    <body>

        <script>
        jQuery.get('yourwebsite.com/file.csv', function(data) {
        document.write(data);
        });
        </script>

    </body>

</html>

生成的输出应该在yourwebsite.com/file.csv上镜像实时数据馈送

如果加载该html页面显示没有输出,请在firefox上按f12打开开发人员控制台。很可能你会看到一个错误:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at yourwebsite.com/file.csv. This can be fixed by moving the resource to the same domain or enabling CORS.

这意味着a)您的httpd.conf未正确配置/未保存,或b)您忘记重新启动Web服务器。


0
投票

在.htaccess文件中,只需添加以下行:

Header set Access-Control-Allow-Origin *
© www.soinside.com 2019 - 2024. All rights reserved.