ChatGPT解决这个技术问题 Extra ChatGPT

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

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

来自服务器的响应如下:

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

我该如何解决这个问题?

使用 jQuery 时,设置 dataType: 'jsonp', 可以解决问题
顺便说一句,这不是来自服务器的响应。准确地说,错误是在客户端发出的。
jsonp 技巧可能不再起作用了,仅供参考:stackoverflow.com/questions/12216208/…
请注意,由于我刚刚浪费了半天时间来追踪这个错误 - 如果服务器端脚本因内部服务器错误而失败,浏览器可能会将其解释为由于 Access-Control-Allow-Origin 而不允许请求并将其报告为错误。

u
user229044

不久前我写了一篇关于这个问题的文章,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') ?>

我会联系我的服务器提供商。谢谢
这有什么安全问题吗?例如,This answer 表示“出于安全原因,JavaScript 受到‘同源策略’的限制,例如,恶意脚本无法联系远程服务器并从您的站点发送敏感数据。”
太棒了,我只是把它放在我的 node.js 服务器文件中: response.writeHead(200, { 'Content-Type': contentType, 'Access-Control-Allow-Origin': '*' });它奏效了。谢谢!
JohnK,是的,通配符将允许任何域向您的主机发送请求。我建议将星号替换为您将在其上运行脚本的特定域。
有趣的是,您认为甚至不应该建议使用通配符@jfrej。这一切都取决于你的目标。例如,我们使用通配符(并发布此答案)的原因是因为我们正在构建一个嵌入式小部件供任何站点使用。
C
Community

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

请注意,我不会将其用于正常的“网上冲浪”。如需参考,请参阅此帖子:Disable same origin policy in Chrome

如果您使用 Phonegap 实际构建应用程序并将其加载到设备上,这将不是问题。


谢谢。但是我的应用程序在移动设备上运行,我无法将参数传递给我的 webview 包装器。
您不先在浏览器中测试您的应用程序吗?你如何调试?
是的,我在 Chrome 浏览器中调试,但该应用程序无法在 Chrome 上运行。它将在我无法控制的 phonegap webview 上。
阅读答案:您可以简单地将这个参数添加到您的 Chrome 启动器中。 Chrome 里面没有这个设置
当然是不安全的。 OP 正在寻求绕过安全措施的方法。
R
Reza S

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

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

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

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

并且不要忘记加载模块:a2enmod 标头
如何加载模块:a2enmod 标头?
P
Peter Mortensen

如果您有 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>

.NET MVC 人,看这里!我实际上要输入一个解决方案并在我的博客上指出这个答案,以便人们更容易找到它。没有什么比试图越过 .NET/MVC 的障碍并只找到 PHP/jQuery 解决方案更糟糕的了。谢谢@Caio-Proiete
这怎么对我不起作用?我正在使用 Chrome 并尝试从我的本地主机访问雅虎财务页面。
谢谢它对我有用。我已经在服务器端代码项目(web.config)中添加了。
t
tagurit

这是我尝试使用 ASP.NET MVC 作为数据源解决相同问题时弹出的第一个问题/答案。我意识到这并不能解决 PHP 问题,但它的相关性足以产生价值。

我正在使用 ASP.NET MVC。 blog post from 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" );
}

WebApi 2 现在内置了这个。 asp.net/web-api/overview/security/…
s
steve0hh

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

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

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

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

https://i.stack.imgur.com/PSSXx.png

然后在“外部主机”下

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

https://i.stack.imgur.com/U7fxd.png


l
lewsid

这对于需要对“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');
 }

为我指明了用 azure 解决 ACAO 错误的正确方向。虽然我添加了允许的 googledrive 主机名。使用的 URL 必须是 googledrive 而不是 googledrive
J
Jonathan Cross

如果您正在编写 Chrome 扩展程序并收到此错误,请确保您已将 API 的基本 URL 添加到 manifest.jsonpermissions block,例如:

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

P
Peter Mortensen

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

创建Chrome浏览器快捷方式右键快捷方式图标->属性->快捷方式->目标

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

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


C
Community

我在使用各种 API 时遇到过几次。通常快速解决方法是添加“&callback=?”到字符串的末尾。有时&符号必须是字符代码,有时是“?”:“?callback =?” (见Forecast.io API Usage with jQuery


t
tagurit

这是因为 same-origin policy。在 Mozilla Developer NetworkWikipedia 中查看更多信息。

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


但是我需要从移动设备加载网络服务,我会绕过这个吗?
那么您需要进行一些服务器端更改或使用 JSONP en.wikipedia.org/wiki/JSONP
a
aydow

如果您在 apache 下,只需将 .htaccess 文件添加到您的目录中,其中包含以下内容:

Header set Access-Control-Allow-Origin: *

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

Header set Access-Control-Allow-Methods: *

P
Peter Mortensen

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

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

如果它是一个ajax调用,你把它放在什么控制器中?我可以看到更多的代码上下文吗?
R
RevanthKrishnaKumar V.

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

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

有关详细信息,请参阅 here


f
forzagreen

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

在 Chrome 中,使用 this extension。如果您使用 Mozilla,请检查 this answer


R
RevanthKrishnaKumar V.

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

批处理:(使用 cmd)

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

M
Mikhail Chuprynski

在红宝石 Sinatra

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

对于每个人或

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

R
RevanthKrishnaKumar V.

当您收到请求时,您可以

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

而不是当你必须回应这样的事情时:

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