如何绕过Access-Control-Allow-Origin?

ETA*_*TAN 191 javascript php ajax jquery cors

我在他们设置的平台上对我自己的服务器进行ajax调用,阻止这些ajax调用(但我需要它从我的服务器获取数据以显示从我服务器的数据库中检索的数据).我的ajax脚本正在运行,它可以将数据发送到我服务器的php脚本以允许它处理.但是,由于它被阻止,它无法获取已处理的数据"Access-Control-Allow-Origin"

我无法访问该平台的源/核心.所以我无法删除它禁止我这样做的脚本.(P/SI使用谷歌Chrome控制台,发现此错误)

Ajax代码如下所示:

 $.ajax({
     type: "GET",
     url: "http://example.com/retrieve.php",
     data: "id=" + id + "&url=" + url,
     dataType: 'json',   
     cache: false,
     success: function(data)
      {
        var friend = data[1];              
        var blog = data[2];           
        $('#user').html("<b>Friends: </b>"+friend+"<b><br> Blogs: </b>"+blog);

      } 
  });
Run Code Online (Sandbox Code Playgroud)

或者JSON上面的ajax脚本是否有相同的代码?我认为JSON是允许的.

我希望有人可以帮助我.

Raf*_*fay 357

把它放在retrieve.php之上:

header('Access-Control-Allow-Origin: *');  
Run Code Online (Sandbox Code Playgroud)

请注意,这有效地禁用了CORS保护,并使您的用户受到攻击.如果您不完全确定需要允许所有来源,则应将其锁定为更具体的来源:

header('Access-Control-Allow-Origin: https://www.example.com')
Run Code Online (Sandbox Code Playgroud)

  • 那是相当不安全的.在底部查看我的答案. (53认同)
  • tnx,但你不应该允许访问@RobQuist在他的评论中提到的所有来源,并且在他的回答中提供了更好的方法 (3认同)
  • 所以我找到了这个页面,因为我需要实际"绕过"服务器上的访问控制.这里的解决方案不是绕过任何东西,只是在他自己的服务器上正确配置访问控制.如果那里的任何人实际上需要绕过它,他们可以使用PHP的file_get_contents($ remote_url);. 显然有很多方法可以做到这一点,但这就是我这样做的方式. (2认同)

Rob*_*Rob 285

好的,但是你们都知道*是一个通配符并允许来自每个域的跨站脚本?

您希望Access-Control-Allow-Origin为每个允许的网站发送多个标头 - 但遗憾的是,它不支持发送多个Access-Control-Allow-Origin标头,或者放置多个来源.

您可以通过检查原点来解决此问题,并在标题中发送回来,如果允许的话:

$origin = $_SERVER['HTTP_ORIGIN'];
$allowed_domains = [
    'http://mysite1.com',
    'https://www.mysite2.com',
    'http://www.mysite2.com',
];

if (in_array($origin, $allowed_domains)) {
    header('Access-Control-Allow-Origin: ' . $origin);
}
Run Code Online (Sandbox Code Playgroud)

那更安全.您可能希望编辑匹配并将其更改为具有某些正则表达式的手动函数,或类似的东西.至少这只会发回1个标题,你将确定它是请求来自的标题.请注意,所有HTTP标头都可以被欺骗,但此标头是为了客户端的保护.不要使用这些值保护您自己的数据.如果您想了解更多信息,请阅读CORS和CSRF.

为什么它更安全?

允许从其他位置访问,然后您自己的可信站点允许会话劫持.我将用一个小例子 - 图片Facebook允许一个通配符来源 - 这意味着你可以在某个地方创建自己的网站,并让它向Facebook发起AJAX调用(或打开iframe).这意味着您可以获取您网站访问者的Facebook的登录信息.更糟糕的是 - 您可以POST在某人的Facebook上编写请求并发布数据 - 就在他们浏览您的网站时.

使用ACAO标题时要非常谨慎!

  • 这是毫无意义的添加4个标题,因为每次调用`header()`都会替换相同类型的前一个标题.所以你真正要做的就是设置最后一个标题.[manual entry](http://php.net/manual/en/function.header.php)声明您可以设置第二个参数`false`以防止覆盖前一个标头. (13认同)
  • 我想你需要把http://放在列表中的每个项目前面.至少我为我正在做的一个网站做过. (11认同)
  • @Shanimal&lewsid - >我猜逗号分隔确实不起作用.参考:http://www.w3.org/TR/cors/ (5认同)
  • 对于域名列表,这里有一个相关的答案:http://stackoverflow.com/a/1850482/766177 (3认同)
  • 可悲的是,这似乎不起作用.我相信每次调用header()时只能提供一个异常. (2认同)
  • @Rafael,是的.这个通配符是mysite1.com上的所有子域名. (2认同)

小智 31

警告,Chrome(和其他浏览器)会抱怨如果您按照其他一些答案设置了多个ACAO标头.

错误将是这样的 XMLHttpRequest cannot load ____. The 'Access-Control-Allow-Origin' header contains multiple values '____, ____, ____', but only one is allowed. Origin '____' is therefore not allowed access.

试试这个:

$http_origin = $_SERVER['HTTP_ORIGIN'];

$allowed_domains = array(
  'http://domain1.com',
  'http://domain2.com',
);

if (in_array($http_origin, $allowed_domains))
{  
    header("Access-Control-Allow-Origin: $http_origin");
}
Run Code Online (Sandbox Code Playgroud)

  • 这是我发布的更好的解决方案. (6认同)

Ati*_*man 7

我在调用MVC3控制器时修复了这个问题.我补充说:

Response.AddHeader("Access-Control-Allow-Origin", "*"); 
Run Code Online (Sandbox Code Playgroud)

在我之前

return Json(model, JsonRequestBehavior.AllowGet);
Run Code Online (Sandbox Code Playgroud)

而且我$.ajax抱怨它在我的ajax调用中不接受Content-type标头,所以我评论它,因为我知道它的JSON被传递给Action.

希望有所帮助.