基本的AJAX请求获得" No' Access-Control-Allow-Origin'标头出现在请求的资源上#34;错误

时间:2016-02-10 00:28:06

标签: javascript jquery ajax cors xmlhttprequest

我尝试向jQuery AJAX请求中的某个链接发送一个简单的GET请求。

这是一个非常简单的问题:

$.ajax({
    type: 'GET',
    url: /* <the link as string> */,
    dataType: 'text/html',
    success: function() { alert("Success"); },
    error: function() { alert("Error"); },
});

然而,无论我尝试过什么,我都得到了XMLHttpRequest cannot load <page>. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:7776' is therefore not allowed access.

我尝试了所有内容,从添加header : {}定义到AJAX请求,再到设置dataTypeJSONP,甚至是text/plain,使用简单的AJAX代替jQuery,甚至下载一个启用CORS的插件 - 但没有任何帮助。

如果我尝试访问任何其他网站,也会发生同样的情况。

有关正确和简单解决方案的任何想法吗?有没有呢?

3 个答案:

答案 0 :(得分:7)

这是设计的。您不能使用XMLHttpRequest向另一台服务器发出任意HTTP请求,除非该服务器通过为请求主机发出Access-Control-Allow-Origin标头来允许它。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

您可以在脚本标记中检索它(对脚本,图像和样式表没有相同的限制),但除非返回的内容是脚本,否则它不会对您有所帮助。< / p>

这是关于CORS的教程:

http://www.bennadel.com/blog/2327-cross-origin-resource-sharing-cors-ajax-requests-between-jquery-and-node-js.htm

这一切都是为了保护最终用户。假设一个图像实际上是一个图像,样式表只是一个样式表,而一个脚本只是一个脚本,从另一个服务器请求这些资源确实不会造成任何伤害。

但总的来说,跨域请求可以做很糟糕的事情。说你,Zoltan,正在使用coolsharks.com。另请注意,您已登录mybank.com并且浏览器中有mybank.com的cookie。现在,假设coolsharks.com向mybank.com发送了一个AJAX请求,要求将所有资金转入另一个帐户。因为您存储了mybank.com cookie,所以他们成功完成了请求。所有这些都是在您不知情的情况下发生的,因为没有发生页面重新加载。这是允许一般跨站点AJAX请求的危险。

如果要执行跨站点请求,您有两种选择:

  1. 获取您要求的服务器 一个。通过发出包含您(或*)
    的Access-Control-Allow-Origin标头来承认您 湾为您提供JSONP API。
    1. 编写自己的浏览器,不遵守标准,没有任何限制。
    2. 在(1)中,您必须与您要求的服务器合作,并且在(2)中,您必须控制最终用户的浏览器。如果你不能完成(1)或(2),那么你几乎没有运气。

      然而,还有第三种选择(charlietfl指出)。您可以从您控制的服务器发出请求,然后将结果传回页面。 E.g。

      <script>
      $.ajax({
          type: 'GET',
          url: '/proxyAjax.php?url=http%3A%2F%2Fstackoverflow.com%2F10m',
          dataType: 'text/html',
          success: function() { alert("Success"); },
          error: function() { alert("Error"); }
      });
      </script>
      

      然后在您的服务器上,最简单的方法:

      <?php
      // proxyAjax.php
      // ... validation of params
      // and checking of url against whitelist would happen here ...
      // assume that $url now contains "http://stackoverflow.com/10m"
      echo file_get_contents($url);
      

      当然,这种方法可能遇到其他问题:

      • 您所代理的网站是否需要正确的推荐人或某个IP地址?
      • 是否需要将Cookie传递到目标服务器?
      • 您的白名单是否足以保护您免受任意请求?
      • 当您的服务器收到这些标题时,您会将哪些标题(例如修改时间等)传回浏览器,哪些标题会被忽略或更改?
      • 您的服务器是否会因为提出非法请求而受到牵连(因为您是代理人)?

      我确定还有其他人。但如果这些问题都没有阻止它,那么第三种方法可以很好地发挥作用。

答案 1 :(得分:3)

你可以问那个域的开发者是否会为你设置合适的标题,这个限制只适用于javascript,基本上你可以用php或者其他任何东西从你的服务器请求ressource,javascript请求你域中的数据然后

答案 2 :(得分:0)

一个老问题,但是我看不到这个解决方案,该解决方案在任何地方都对我有用。因此希望这对某人有帮助。

首先,请记住,尝试修改请求的标头以解决跨域资源请求是没有意义的。如果已采取了所有措施,那么恶意用户很容易绕开此安全措施。

只有在合作伙伴网站的服务器通过其响应标头允许它的情况下,跨域请求才有可能。

通过在响应中设置以下标头,我可以在没有任何CORS中间件的情况下在Django中工作:

    response["Access-Control-Allow-Origin"] = "requesting_site.com"
    response["Access-Control-Allow-Methods"] = "GET"
    response["Access-Control-Allow-Headers"] = "requesting_site.com"

这里的大多数答案似乎都提到了第一个,但没有提到第二个。我刚刚确认它们都是必需的。您需要根据需要修改框架或请求方法(GET,POST,OPTION)。

p.s。您可以尝试"*"而不是"requesting_site.com"进行初始开发,只是为了使其正常运行,但这是允许每个网站访问的安全漏洞。一旦工作,您就只能将其限制在请求的网站上,以确保没有任何格式错误。