Access-Control-Allow-Origin不允许起源


337

我正在Ajax.request使用Sencha Touch 2应用程序(包装在PhoneGap中)到远程PHP服务器。

来自服务器的响应如下:

XMLHttpRequest无法加载http://nqatalog.negroesquisso.pt/login.php。原产地http://localhost:8888不被访问控制允许来源允许的。

我该如何解决这个问题?


19
在使用jQuery时,设置dataType: 'jsonp',可以解决问题
2012年

11
顺便说一句,这不是服务器的响应。确切地说,该错误是在客户端发出的。
matteo

2
jsonp技巧可能不再起作用了,仅供参考:stackoverflow.com/questions/12216208/…–
drewww

7
请注意,由于我浪费了半天时间来追查该错误-如果服务器端脚本因内部服务器错误而失败,则浏览器可能会将其解释为由于不允许该请求而将Access-Control-Allow-Origin其报告为错误。
troelskn

1
@troelskn您刚刚救了我的命。自3天以来,我一直在寻找一些CORS错误,这只是一个导致500的Spring配置问题,当我阅读您的评论并真正在寻找它时,我在5分钟内解决了该问题。谢谢!
亚历克西斯·杜夫洛诺伊

Answers:


378

不久前,我写了一篇有关此问题的文章Cross Domain AJAX

如果您控制响应服务器,最简单的方法是为以下项添加响应标头:

Access-Control-Allow-Origin: *

这将允许跨域Ajax。在PHP中,您将需要像这样修改响应:

<?php header('Access-Control-Allow-Origin: *'); ?>

您可以将Header set Access-Control-Allow-Origin *设置放入Apache配置或htaccess文件中。

应该注意的是,这有效地禁用了CORS保护,这很可能使您的用户受到攻击。如果您不知道自己是否特别需要使用通配符,则不要使用它,而应该将特定域列入白名单:

<?php header('Access-Control-Allow-Origin: http://example.com') ?>

4
我将与服务器提供商联系。谢谢
里卡多

8
与此相关的安全问题吗?例如,此答案说:“出于安全原因,JavaScript受“相同来源策略”限制,例如,恶意脚本无法联系远程服务器并从您的站点发送敏感数据。”
JohnK

4
太棒了,我只是将其放在我的node.js服务器文件中:response.writeHead(200,{'Content-Type':contentType,'Access-Control-Allow-Origin':'*'}); 而且有效。谢谢!
vbullinger

25
JohnK,是的,通配符将允许任何域向您的主机发送请求。我建议将星号替换为将在其上运行脚本的特定域。
尼克

7
有趣的是,您认为甚至不应建议使用通配符@jfrej。这完全取决于您的目标。例如,我们使用通配符(并发布了此答案)的原因是因为我们正在为任何站点使用构建嵌入式小部件。
Matt Mombrea 2013年

63

如果您无法控制服务器,则只需将此参数添加到您的Chrome启动器中:--disable-web-security

请注意,我不会将其用于常规的“网络冲浪”。作为参考,请参阅这篇文章:在Chrome中禁用同一来源策略

您可以使用Phonegap实际构建应用程序并将其加载到设备上,这不会成为问题。


谢谢。但是我的应用程序正在移动设备上运行,我无法将参数传递给Webview包装器。
里卡多

您不先在浏览器中测试您的应用程序吗?您如何调试?
特拉维斯·韦伯

是的,我在Chrome浏览器中进行了调试,但该应用程序无法在chrome上运行。这将是我无法控制的phonegap webview女巫。
里卡多

4
阅读答案:您可以简单地将此参数添加到Chrome启动器中。Chrome内部没有为此设置
Travis Webb 2013年

2
当然是不安全的。OP正在寻求解决安全措施的方法。
特拉维斯·韦伯

42

如果您使用的是Apache,只需添加:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</ifModule>

在您的配置中。这将使您可以从Internet上的任何其他站点访问来自Web服务器的所有响应。如果您打算仅允许主机上的服务由特定服务器使用,则可以将替换*为原始服务器的URL:

Header set Access-Control-Allow-Origin: http://my.origin.host

3
并且不要忘记加载模块:a2enmod标头
Walery Strauch

如何加载module:a2enmod头文件?
Ayesha

18

如果您有ASP.NET / ASP.NET MVC应用程序,则可以通过Web.config文件包含此标头:

<system.webServer>
  ...

    <httpProtocol>
        <customHeaders>
            <!-- Enable Cross Domain AJAX calls -->
            <remove name="Access-Control-Allow-Origin" />
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

2
.NET MVC人士,请点击此处!我实际上将输入解决方案并在我的博客上指向此答案,以便人们可以更轻松地找到它。没有什么比尝试克服.NET / MVC障碍和发现PHP / jQuery解决方案更糟糕的了。感谢@ Caio-Proiete
ottoflux 2013年

1
为什么这对我不起作用?我正在使用Chrome,并尝试从本地主机访问yahoo财务页面。
纽曼2014年

1
谢谢它为我工作。我已经在服务器端代码项目(web.config)中添加了。
ethem 2015年

15

这是我尝试使用ASP.NET MVC作为数据源来解决相同问题时出现的第一个问题。我意识到这并不能解决PHP问题,但它具有足够的相关性,因此很有价值。

我正在使用ASP.NET MVC。Greg Brant博客文章为我工作。最终,您将创建一个属性,[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]您可以将其添加到控制器操作中。

例如:

public class HttpHeaderAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }
    public HttpHeaderAttribute(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.AppendHeader(Name, Value);
        base.OnResultExecuted(filterContext);
    }
}

然后将其用于:

[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
    return Json( "Some public result" );
}

1
WebApi 2现在内置了此功能。asp.net/web-api/overview/security/...
马特Frear

10

由于Matt Mombrea在服务器端是正确的,因此您可能会遇到另一个问题,即将拒绝列入白名单。

您必须配置phonegap.plist。(我使用的是旧版的phonegap)

对于cordova,命名和目录可能会有一些更改。但是步骤应该大致相同。

首先选择支持文件> PhoneGap.plist

在此处输入图片说明

然后在“外部主机”下

添加一个条目,其值可能为“ http://nqatalog.negroesquisso.pt ”。我仅将*用于调试目的。

在此处输入图片说明


8

这对于需要为引荐来源网址的“ www”和“ non-www”版本都需要例外的任何人来说都非常方便:

 $referrer = $_SERVER['HTTP_REFERER'];
 $parts = parse_url($referrer);
 $domain = $parts['host'];

 if($domain == 'google.com')
 {
         header('Access-Control-Allow-Origin: http://google.com');
 }
 else if($domain == 'www.google.com')
 {
         header('Access-Control-Allow-Origin: http://www.google.com');
 }

为我指出正确的方向,以天蓝色解决ACAO错误。虽然我已添加允许的googledrive主机名。URL中使用的需求是Google云端硬盘不是Google云端硬盘
Kildareflare

7

我将为您提供一个简单的解决方案。就我而言,我无权访问服务器。在这种情况下,您可以在Google Chrome浏览器中更改安全策略以允许Access-Control-Allow-Origin。这很简单:

  1. 创建Chrome浏览器快捷方式
  2. 右键单击快捷方式图标->属性->快捷方式->目标

简单粘贴"C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security

位置可能会有所不同。现在,点击该快捷方式打开Chrome。



6

如果您正在编写Chrome扩展程序并遇到此错误,请确保已将API的基本URL添加到manifest.json权限块中,例如:

"permissions": [
    "https://itunes.apple.com/"
]


6

如果您使用的是Apache,只需将.htaccess文件添加到包含以下内容的目录中:

Header set Access-Control-Allow-Origin: *

Header set Access-Control-Allow-Headers: content-type

Header set Access-Control-Allow-Methods: *

5

Ruby on Rails中,您可以在控制器中执行以下操作:

headers['Access-Control-Allow-Origin'] = '*'

如果是ajax调用,您将其放在哪个控制器中?我可以查看更多代码上下文吗?
rigdonmr 16-10-12

5

您可以通过使浏览器Access-Control-Allow-Origin: *在HTTP OPTIONS响应中包括标头来使其工作而无需修改服务器。

在Chrome中,使用此扩展程序。如果您使用Mozilla,请检查此答案


5

如果您在Angular.js中获得此权限,请确保您像这样转义端口号:

var Project = $resource(
    'http://localhost\\:5648/api/...', {'a':'b'}, {
        update: { method: 'PUT' }
    }
);

有关更多信息,请参见此处


4

对于在chrome中测试过的phonegap应用程序,我们也有同样的问题。打开Chrome之前,我们每天都会使用下面的批处理文件使用一台Windows计算机。请记住,在运行此程序之前,您需要从任务管理器中清除所有chrome实例,或者您可以选择chrome不在后台运行。

批量:(使用cmd)

cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security


0

收到请求后,您可以

var origin = (req.headers.origin || "*");

而不是当您必须做出回应时,就可以像这样:

res.writeHead(
    206,
    {
        'Access-Control-Allow-Credentials': true,
        'Access-Control-Allow-Origin': origin,
    }
);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.