关于javascript:请求的资源上没有“Access-Control-Allow-Origin”标头。 因此不允许原点’…’访问

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '…' is therefore not allowed access

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

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

XMLHttpRequest cannot load http://www.example.com/login.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://example.com' is therefore not allowed access.


使用addHeader而不是使用setHeader方法,

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

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

允许access to specific domain only

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

检查此blog post


为什么会出现错误:

JavaScript代码受同源策略的限制,这意味着,从www.example.com的页面,您只能向位于完全相同域的服务发出(AJAX)请求,在这种情况下,确切地www.example.com(不是 - 没有www - 或whatever.example.com)。

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

虽然非常相似,但它们不是同一个域。当它们不在同一个域上时,只有当目标的respose包含一个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添加到目标域。当然,添加它取决于该地址背后的服务器/语言。有时,工具中的配置变量可以解决问题。其他时候你必须自己通过代码添加标题。


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

1
2
3
4
5
6
7
 <system.webServer>
   <httpProtocol>
     <customHeaders>
       
     </customHeaders>
   </httpProtocol>
 </system.webServer>

比方说,如果服务器域是http://live.makemypublication.com,客户端是http://www.makemypublication.com,那么在服务器的web.config中配置如下

1
2
3
4
5
6
7
 <system.webServer>
   <httpProtocol>
     <customHeaders>
       
     </customHeaders>
  </httpProtocol>
 </system.webServer>


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

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '…' is therefore not allowed access

当您尝试向远程服务器执行Ajax POST / GET请求时,请忘记这个简单的修复:

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

您真正需要做的事情,特别是如果您只使用JavaScript来执行Ajax请求,是一个内部代理,它会将您的查询发送到远程服务器。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
$.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绕过此问题:

1
2
3
4
5
6
7
8
9
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));
 }

通过做:

1
 echo json_encode(file_get_contents($url));

你只是在同一个查询,但在服务器端,之后,它应该工作正常。


你需要在你的php页面"login.php"的开头添加它

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


你必须在选项方法响应中放置标题键/值。
例如,如果您有http://mydomain.com/myresource的资源
然后,在您编写的服务器代码中

1
2
3
4
5
6
7
8
9
10
11
//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");
    }



}


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

Access-Control-Allow-Credentials:true

Access-Control-Allow-Origin:*

但就安全性而言,这不是一个好的解决方案


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

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

或Apache反向代理......


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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
#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}]]

当我使用Angular将记录发布到Django REST后端时,我遇到了这个问题。有时,这个问题没有特别的原因。仔细检查您的Django的错误消息,您将找到一个解决方案。