所请求的资源上没有“ Access-Control-Allow-Origin”标头。因此,不允许访问来源“ ...”


135

我正在使用.htaccess重写网址,并使用了html基本标记以使其正常工作。

现在,当我尝试发出ajax请求时,出现以下错误:

XMLHttpRequest无法加载http://www.example.com/login.php。所请求的资源上没有“ Access-Control-Allow-Origin”标头。http://example.com因此,不允许访问来源' '。


1
没关系...它现在正在工作,我什至不知道这是什么错误:S
Th3lmuu90

8
Altough微妙,http://wordicious.com是一个不同的域http://www.wordicious.com/,从而该错误。顺便说一句,如果它现在可以正常工作并且可以自行恢复,则可能应该删除该问题。
acdcjunior 2013年

@acdcjunior这似乎是错误,这对您来说是一种敏锐的观察。如果您将其发布为答案,我会投票赞成。
Waleed Khan 2013年

5
好的问题没有被删除,或者我今天不会看到它!
icedwater

Answers:


170

使用addHeader代替使用setHeader方法,

response.addHeader("Access-Control-Allow-Origin", "*");

*在上面的行中将允许access to all domains


允许access to specific domain only

response.addHeader("Access-Control-Allow-Origin", "http://www.example.com");

检查一下blog post


4
它显示未定义addheader。你能解释一下吗?
Vaisakh Pc 2014年

9
这些线放在哪里?
DaveWalley 2014年

14
应该在哪里添加?
Alex

1
那篇博客文章谈论的是Node.js和express。不是客户端javascript。谁能确认这是否有效?
山姆·伊顿

1
我不认为只能在客户端上进行此配置。.关于放置它的位置,它将在服务器端代码中(大概是在构建对请求的响应时)
Chirag Ravindra

145

为什么会引发错误:

JavaScript代码受到同源策略的限制,也就是说,从的页面上www.example.com,您只能向完全相同域中的服务发出(AJAX)请求,在这种情况下,您必须完全www.example.com example.com -不带www-或whatever.example.com)。

在您的情况下,您的Ajax代码试图http://wordicious.com从位于的页面访问服务http://www.wordicious.com

尽管非常相似,但它们不是同一域。并且当它们不在同一域中时,仅当目标的居所中包含Access-Control-Allow-Origin标头时,请求才会成功。

作为您的页面/服务,位于 http://wordicious.com从未配置为显示此类标题,因此将显示该错误消息。

解:

如前所述,原始域(使用JavaScript的页面所在的位置)和目标域(JavaScript尝试到达的位置)必须准确

您的案子看起来像错字。看起来http://wordicious.comhttp://www.wordicious.com实际上是相同的服务器/域。因此,要解决此问题,请平等地键入目标和来源:使您的Ajax代码请求页面/服务http://www.wordicious.com不为http://wordicious.com。(也许相对地放置目标URL,例如'/login.php',不带域)。



一般而言:

如果问题不是该问题的错字,则解决方案是将添加Access-Control-Allow-Origin到目标域。要添加它,当然取决于该地址后面的服务器/语言。有时,工具中的配置变量可以解决问题。其他时候,您必须自己通过代码添加标头。


62

对于.NET服务器,可以在web.config中进行配置,如下所示

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="your_clientside_websiteurl" />
     </customHeaders>
   </httpProtocol>
 </system.webServer>

例如,假设服务器域为http://live.makemypublication.com,客户端为 http://www.makemypublication.com,则在服务器的web.config中进行如下配置

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="http://www.makemypublication.com" />
     </customHeaders>
  </httpProtocol>
 </system.webServer>

更好的解决方案。谢谢
ANJYR-KODEXPRESSION

非常感谢。你救了我一整天。
Prateek Gupta

即使在2年后仍可工作:p
无处不在的开发人员

1
@SyedAliTaqi问题是php,这就是为什么答案被低估了的原因。但是它也对我有用:)
艾哈迈德(Ahmad Th)

22

如果您从浏览器中收到此错误消息:

所请求的资源上没有“ Access-Control-Allow-Origin”标头。因此,不允许访问来源“ ...”

当您尝试对无法控制的远程服务器发出Ajax POST / GET请求时,请忽略以下简单解决方法:

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

您真正需要做的是一个内部代理,特别是如果您仅使用JavaScript来执行Ajax请求时,它可以接收您的查询并将其发送到远程服务器。

首先,在您的JavaScript中,对您自己的服务器进行Ajax调用,例如:

$.ajax({
    url: yourserver.com/controller/proxy.php,
    async:false,
    type: "POST",
    dataType: "json",
    data: data,
    success: function (result) {
        JSON.parse(result);
    },
    error: function (xhr, ajaxOptions, thrownError) {
        console.log(xhr);
    }
});

然后,创建一个名为proxy.php的简单PHP文件,以包装您的POST数据并将其作为参数附加到远程URL服务器。我举一个例子,说明如何使用Expedia Hotel搜索API绕过此问题:

if (isset($_POST)) {
  $apiKey = $_POST['apiKey'];
  $cid = $_POST['cid'];
  $minorRev = 99;

  $url = 'http://api.ean.com/ean-services/rs/hotel/v3/list?' . 'cid='. $cid . '&' . 'minorRev=' . $minorRev . '&' . 'apiKey=' . $apiKey;

  echo json_encode(file_get_contents($url));
 }

通过做:

 echo json_encode(file_get_contents($url));

您只是在执行相同的查询,但是在服务器端,此后它应该可以正常工作。


@NizarBsb,你疯了,你知道!:D,非常感谢您的回答挽救了我的性命
Flash


7

您必须将标头键/值放在选项方法响应中。例如,如果您在http://mydomain.com/myresource上拥有资源, 则在服务器代码中编写

//response handler
void handleRequest(Request request, Response response) {
    if(request.method == "OPTIONS") {
       response.setHeader("Access-Control-Allow-Origin","http://clientDomain.com")
       response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
       response.setHeader("Access-Control-Allow-Headers", "Content-Type");
    }



}

3

基本上,通过添加以下附加参数来更改API标头响应。

访问控制允许凭据:true

访问控制允许来源:*

但这不是安全性的好解决方案


3

解决方法是使用运行在“源”主机上的反向代理并将其转发到目标服务器,例如Fiddler:

链接在这里:http : //docs.telerik.com/fiddler/configure-fiddler/tasks/usefiddlerasreverseproxy

或Apache反向代理...


可以在域的Apache或Nginx配置级别上完成此操作。例如,如果用户正在访问mysite.com(无www)而XHR正在请求www.mysite.com,那么htaccess或httpd.conf指令可以解决此问题吗?
codecowboy 2014年

当然,您的前端应用程序应充当反向代理。例如对于Apache,您必须安装mod_proxy,并使用ProxyPassReverse(httpd.apache.org/docs/current/mod/…)配置规则。Nginx上似乎也具有相同的功能:wiki.nginx.org/LikeApache
hzrari 2014年

2

将此添加到您的PHP文件或主控制器

header("Access-Control-Allow-Origin: http://localhost:9000");

完成-您还需要header("Access-Control-Allow-Credentials: true");
亚当(Adam)

1

解决了httpd.conf中的以下条目

#CORS Issue
Header set X-Content-Type-Options "nosniff"
Header always set Access-Control-Max-Age 1728000
Header always set Access-Control-Allow-Origin: "*"
Header always set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT,PATCH"
Header always set Access-Control-Allow-Headers: "DNT,X-CustomHeader,Keep-Alive,Content-Type,Origin,Authentication,Authorization,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control"
Header always set Access-Control-Allow-Credentials true

#CORS REWRITE
RewriteEngine On                  
RewriteCond %{REQUEST_METHOD} OPTIONS 
#RewriteRule ^(.*)$ $1 [R=200,L]
RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]]

对我而言,在Apache2,CentOS7,Larravel 5和React上起作用的唯一方法是
Shakiba Moshiri,

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.