【问题标题】:Cross Origin Resource Sharing (CORS) and Javascript跨域资源共享 (CORS) 和 Javascript
【发布时间】:2014-03-20 02:16:49
【问题描述】:

我们以这个 url 为例:http://api.duckduckgo.com/?q=computer&format=json(此服务器上未启用 CORS!)

  1. 我们可以从任何流行的浏览器访问这个 URL 中的内容,就像普通 URL 一样,浏览器打开这个 URL 没有问题,服务器也没有返回任何错误。

  2. 像 PHP/RoR 这样的服务器端语言可以从这个 URL 获取内容,而无需添加任何额外的标头或特殊的服务器设置。我使用了以下 PHP 代码,它很简单。

    $url='http://api.duckduckgo.com/?q=computer&format=json';
    $json = file_get_contents($url);
    echo $json;
    
  3. 我刚开始在 javascript 框架 AngularJS 中工作。我使用了以下代码...

    delete $http.defaults.headers.common['X-Requested-With'];
    var url="http://api.duckduckgo.com/?q=computer&format=json";
    $http.get(url)
         .success(function(data) {
             $scope.results=data;
          })
    

    使用上面的 AngularJS 代码,我收到以下错误:

    XMLHttpRequest 无法加载 http://api.duckduckgo.com/?q=computer&format=json。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问 Origin 'http://localhost:63342'。

  4. AngularJS 使用 JQuery,所以我在 JQuery 中尝试了相同的代码:

    var url="http://api.duckduckgo.com/?q=computer&format=json";
    $.getJSON(url , function( data ) {
        console.log(data);
    });
    

    这也产生了与 AngularJS 代码相同的错误。

  5. 然后我的进一步研究使我意识到它实际上并不特定于 JQuery 和 AngularJS。这两个都从 Javascript 继承了这个问题!



所以我的问题不是 CORS 是什么。我的问题是

  1. 我的理解是,不管是网页浏览器还是PHP/RoR还是Javascript框架,都是通过同一个http或者https向一个URL发出请求的,对吧?当然,是的。那么为什么当请求来自 javascript 时,http 必须更安全呢? http 和服务器如何知道请求来自 javascript?

  2. 当网络浏览器可以打开一个 URL 并且 PHP/RoR(或任何服务器端语言)可以在没有任何额外设置/标题的情况下访问该 URL,为什么 AngularJS、JQuery 不能javascript) 访问该 URL,除非服务器已设置 Access-Control-Allow-Origin 标头以请求 root?

  3. Javascript 中缺少什么特殊功能(PHP/RoR 具有和),因此它无法在相同的浏览器中访问相同的 URL,而这些浏览器可以在地址栏中打开该 URL 而不会出现任何问题?

顺便提一下,我基本上是一名 iOS 开发人员,最近开始学习 Web 开发,特别是 AngularJS。所以我很好奇这一切发生了什么以及为什么!

【问题讨论】:

  • "那么当请求来自 javascript 时,为什么 http 必须更安全?" 因为 Ajax 请求是作为用户发出的,带有他们的 cookie ,包括任何会话等。因此,如果您已登录并且默认允许跨域,则恶意 Web 应用程序可能会向您的银行余额和报表发出 Ajax 请求并成功。
  • 一个可能的原因可能是脚本注入,如果您是标准用户并访问某个网页,那么您信任那个页面。如果该页面试图涉及另一个域,那么它将要求您信任它,默认情况下它被拒绝而不是请求许可。 (这是我个人的理解,如有错误请指正)
  • @Nunners 作为用户,您不知道是否允许域 A 与域 B 通信,您在握手 [CORS] 中没有发言权。
  • @JonathanLonowski,很高兴知道 :) 感谢您对 Ajax 的快速提示!

标签: javascript jquery angularjs cors


【解决方案1】:

出于安全原因,它已从 javascript 中禁用。这是一种情况:

  • 假设 Facebook 有一个“在时间轴上发布消息”API,需要对用户进行身份验证。
  • 当您访问 badsite.com 时,您已登录 Facebook。
  • badsite.com 使用 javascript 调用 Facebook api。由于浏览器向 Facebook 发出有效请求,您的身份验证 cookie 被发送,Facebook 接受该消息并在您的时间线上发布 badsite 的广告。

这不是服务器的问题,因为 badsite.com 的服务器无权访问您的 Facebook 身份验证 cookie,也无法代表您伪造有效请求。

【讨论】:

  • 是的,这是有道理的!
  • 那么知道 JS 可以访问客户端机器上的 cookie 和会话,除了 CORS 之外,还有其他 HTTP 功能已被 javascript 禁用吗?还有其他可能的安全漏洞吗?
  • 不太清楚你在问什么,但有很多可能的安全漏洞。查看OWASP Top 10
【解决方案2】:

你记得所有的 javascript 请求都是由浏览器处理的。所以浏览器检测跨域请求很容易。

来自javascript的请求与PHP/RoR没有区别,只是被浏览器拒绝。

服务器代码可以通过标头“Access-Control-Allow-Origin”接受跨域javascript请求,因为在拒绝javascript请求之前,浏览器会向服务器发送请求“OPTIONS”以询问标头“Access-Control-Allow-Origin” “关于回应。如果值与当前来源匹配,浏览器将接受 javascript 请求并发送到服务器。

所有浏览器都执行此政策Same Origin Policy

【讨论】:

  • 赞成指出“选项”以及浏览器如何允许 javascript 请求,谢谢 :)
【解决方案3】:

请阅读http://en.wikipedia.org/wiki/Cross-site_scripting,您将了解其禁止 JavaScript 的原因。

【讨论】: