Access-Control-Allow-Origin不允许Origin

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

服务器的响应如下:

XMLHttpRequest无法加载http://nqatalog.negroesquisso.pt/login.php。Access-Control-Allow-Origin不允许Origin http://localhost:8888

我该如何解决这个问题?

766096 次浏览

这是因为同源策略。参见Mozilla开发者网络维基百科

基本上,在你的例子中,你只需要从nqatalog.negroesquisso.pt加载http://nqatalog.negroesquisso.pt/login.php页面,而不是localhost

我曾经写过一篇关于这个问题的文章,跨域AJAX

如果你有响应服务器的控制权,最简单的方法是添加一个响应头:

Access-Control-Allow-Origin: *

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

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

你可以把Header set Access-Control-Allow-Origin *设置放在Apache配置或htaccess文件中。

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

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

如果你拥有服务器的控制权,你可以简单地将这个参数添加到你的Chrome启动器:

注意,我不会将它用于正常的“网上冲浪”。如需参考,请参阅这篇文章:在Chrome中禁用同源策略

如果你使用Phonegap来构建应用并将其加载到设备上,这就不是问题了。

正如Matt Mombrea在服务器端所说的那样,你可能会遇到另一个问题,即白名单拒绝。

你必须配置你的phonegap。plist。(我正在使用旧版本的phonegap)

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

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

enter image description here

然后在“ExternalHosts”下面

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

enter image description here

如果你正在使用Apache,只需添加:

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

在构型中。这将导致来自您的web服务器的所有响应都可以从互联网上的任何其他站点访问。如果你打算只允许你的主机上的服务被特定的服务器使用,你可以用初始服务器的URL替换*:

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

在使用各种api时,我遇到过几次这种情况。通常一个快速的解决方法是在字符串的末尾添加“&callback=?”有时&号必须是字符代码,有时是“?””:“回调= ?”(见预测。jQuery的API使用)

我们在chrome测试phonegap应用程序时也有同样的问题。 在打开Chrome之前,我们每天使用下面的批处理文件。 记住在运行这个之前,你需要从任务管理器中清除所有的chrome实例,或者你可以选择chrome不运行在后台

BATCH:(使用cmd)

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

如果你在Angular.js中得到这个,那么确保你像这样转义你的端口号:

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

有关它的更多信息,请参阅在这里

当我试图用ASP。NET MVC作为数据源来解决同样的问题时,这是第一个跳出来的问题/答案。我意识到这并不能解决PHP问题,但它是有价值的。

我使用ASP。净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" );
}

这可能对任何需要为引用器的'www'和'非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');
}

如果你有一个ASP。网 / ASP。NET MVC应用程序,你可以通过Web包含这个头文件。配置文件:

<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>

Ruby on Rails中,你可以在控制器中执行:

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

我会给你一个简单的解决方法。就我而言,我没有访问服务器的权限。在这种情况下,您可以在谷歌Chrome浏览器中更改安全策略,以允许访问控制-允许起源。这很简单:

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

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

位置可能不同。现在通过点击快捷方式打开Chrome。

如果你正在编写一个Chrome扩展并得到这个错误,那么请确保你已经将API的基本URL添加到你的manifest.json权限块中,例如:

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

当您收到请求时,您可以

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

而当你不得不这样回答的时候:

res.writeHead(
206,
{
'Access-Control-Allow-Credentials': true,
'Access-Control-Allow-Origin': origin,
}
);

你可以在不修改服务器的情况下让浏览器在HTTP OPTIONS的响应中包含Access-Control-Allow-Origin: *头来让它工作。

在Chrome中,使用这个扩展。如果你在Mozilla检查这个答案

在Ruby中辛纳特拉

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

对每个人来说

response['Access-Control-Allow-Origin'] = 'http://yourdomain.name'

如果你在apache下,只需添加一个。htaccess文件到你的目录,内容如下:

Header set Access-Control-Allow-Origin: *


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


Header set Access-Control-Allow-Methods: *