跨域资源共享(CORS)概念

时间:2014-08-14 14:21:13

标签: javascript jquery ajax cors

我对跨域JavaScript概念有疑问。

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

  

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

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

但是如果使用亚马逊网络服务的某些域名是选定的域名之一,则会有一个JavaScript,如果我们在html中包含它,它就可以运行。

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

他们有一种方法可以通过Ajax获得响应。

我的问题是:

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

4 个答案:

答案 0 :(得分:40)

重要提示:如果另一端的服务器未启用它,那么您的客户端代码中无法执行任何操作跨性别的ajax请求。

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

Same-Origin Security Policy

简单地说,同源安全策略可确保来自一个源的脚本可能无法从其他来源获取内容。现在向您解释原始概念,让我引用Wikipedia article of Same-Origin Security Policy

的一部分
  

下表概述了针对网址“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:password@www.example.com/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(又名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一起正常工作的调用;现在已经过时了,所有现代浏览器(包括来自Microsoft)都会在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文件下载到从选定域提供的页面。

回答编号的问题:

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

答案 1 :(得分:4)

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

您可以从“script”标记中访问页面的原因是,标记的处理方式与跨源请求的所有其他数据的处理方式不同。在过去,您可以使用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服务器。

答案 2 :(得分:0)

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

Header set Access-Control-Allow-Origin *

答案 3 :(得分:0)

这不是前端的问题,这是后端的问题。您应该在后端允许CORS来源。

我正在使用Django。并添加CORS中间件并允许CORS_ORIGINS解决该问题。

添加CORS中间装

MIDDLEWARE = [
...
'corsheaders.middleware.CorsMiddleware',
...
]

并允许CORS。您可以允许所有来源,也可以仅允许特定来源。

CORS_ORIGIN_ALLOW_ALL = True

仅允许特定来源

CORS_ORIGIN_ALLOW_ALL = False

CORS_ORIGIN_WHITELIST = (
    '<YOUR_DOMAIN>[:PORT]',
)

一个例子:

CORS_ORIGIN_ALLOW_ALL = False

CORS_ORIGIN_WHITELIST = (
    '127.0.0.1:3000', 'frontend.com',
)