我正在使用.htaccess重写网址,我使用了html基本标记以使其正常工作 .
现在,当我尝试发出ajax请求时,我收到以下错误:
XMLHttpRequest无法加载http://www.wordicious.com/login.php . 请求的资源上不存在“Access-Control-Allow-Origin”标头 . 因此,不允许来源“http://wordicious.com”访问 .
解决方法是使用在“源”主机上运行的反向代理并转发到目标服务器,例如Fiddler:
链接在这里:http://docs.telerik.com/fiddler/configure-fiddler/tasks/usefiddlerasreverseproxy
或Apache反向代理......
将此添加到PHP文件或主控制器
header("Access-Control-Allow-Origin: http://localhost:9000");
JavaScript代码受same-origin policy的限制,这意味着,从 www.example.com 的页面,您只能向位于 exactly 的同一域的服务发出(AJAX)请求,在这种情况下,确切 www.example.com ( not example.com - 没有 www - 或 whatever.example.com ) .
www.example.com
example.com
www
whatever.example.com
在您的情况下,您的Ajax代码正试图从位于 http://www.wordicious.com 的页面中 http://wordicious.com 中获取服务 .
http://www.wordicious.com
http://wordicious.com
虽然非常相似,但它们是 not 相同的域名 . 当它们不在同一个域中时,只有当目标的respose包含 Access-Control-Allow-Origin 标头时,该请求才会成功 .
Access-Control-Allow-Origin
由于 http://wordicious.com 处的页面/服务从未配置为显示此标头,因此会显示该错误消息 .
如上所述,原点(带有JavaScript的页面所在的位置)和目标(JavaScript试图访问的域)必须与_307067相同 .
你的案子似乎是一个错字 . 看起来像 http://wordicious.com 和 http://www.wordicious.com 实际上是相同的服务器/域 . 所以要修复,同样键入目标和原点: make you Ajax code request pages/services to http://www.wordicious.com not http://wordicious.com . (可能相对地放置目标URL,如 '/login.php' ,没有域) .
'/login.php'
如果问题不是像这个问题那样的错字,那么解决方案就是 add the Access-Control-Allow-Origin to the target domain . 当然,要添加它,取决于该地址背后的服务器/语言 . 有时工具中的配置变量可以解决问题 . 其他时候你必须自己通过代码添加 Headers .
你必须在选项方法响应中放置 Headers 键/值 . 例如,如果您在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"); } }
解决了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}]]
对于.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>
如果您从浏览器收到此错误消息:
请求的资源上没有“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));
你只是在同一个查询,但在服务器端,之后,它应该工作正常 .
通过添加以下附加参数,基本上改变API头响应 .
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:*
但就安全性而言,这不是一个好的解决方案
你需要在你的php页面“login.php”的开头添加它
当我使用 Angular 将记录发布到 Django REST 后端时,我遇到了这个问题 . 有时,这个问题没有特别的原因 . 仔细检查您的Django的错误消息,您将找到一个解决方案 .
Angular
Django REST
使用 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 .
11 回答
解决方法是使用在“源”主机上运行的反向代理并转发到目标服务器,例如Fiddler:
链接在这里:http://docs.telerik.com/fiddler/configure-fiddler/tasks/usefiddlerasreverseproxy
或Apache反向代理......
将此添加到PHP文件或主控制器
为什么会引发错误:
JavaScript代码受same-origin policy的限制,这意味着,从
www.example.com
的页面,您只能向位于 exactly 的同一域的服务发出(AJAX)请求,在这种情况下,确切www.example.com
( notexample.com
- 没有www
- 或whatever.example.com
) .在您的情况下,您的Ajax代码正试图从位于
http://www.wordicious.com
的页面中http://wordicious.com
中获取服务 .虽然非常相似,但它们是 not 相同的域名 . 当它们不在同一个域中时,只有当目标的respose包含
Access-Control-Allow-Origin
标头时,该请求才会成功 .由于
http://wordicious.com
处的页面/服务从未配置为显示此标头,因此会显示该错误消息 .解决方案:
如上所述,原点(带有JavaScript的页面所在的位置)和目标(JavaScript试图访问的域)必须与_307067相同 .
你的案子似乎是一个错字 . 看起来像
http://wordicious.com
和http://www.wordicious.com
实际上是相同的服务器/域 . 所以要修复,同样键入目标和原点: make you Ajax code request pages/services to http://www.wordicious.com not http://wordicious.com . (可能相对地放置目标URL,如'/login.php'
,没有域) .更一般的说明:
如果问题不是像这个问题那样的错字,那么解决方案就是 add the Access-Control-Allow-Origin to the target domain . 当然,要添加它,取决于该地址背后的服务器/语言 . 有时工具中的配置变量可以解决问题 . 其他时候你必须自己通过代码添加 Headers .
你必须在选项方法响应中放置 Headers 键/值 . 例如,如果您在http://mydomain.com/myresource有资源,那么在您编写的服务器代码中
解决了httpd.conf中的以下条目
对于.NET服务器,可以在web.config中进行配置,如下所示
例如,假设服务器域为http://live.makemypublication.com且客户端为http://www.makemypublication.com,则在服务器的web.config中进行配置,如下所示
如果您从浏览器收到此错误消息:
当您尝试向无法控制的远程服务器执行Ajax POST / GET请求时,请忘记这个简单的修复:
您真正需要做的事情,特别是如果您只使用JavaScript来执行Ajax请求,是一个内部代理,它会接收您的查询并将其发送到远程服务器 .
首先在您的JavaScript中,对您自己的服务器执行Ajax调用,例如:
然后,创建一个名为proxy.php的简单PHP文件来包装POST数据,并将它们作为参数附加到远程URL服务器 . 我举例说明了如何使用Expedia Hotel搜索API绕过此问题:
通过做:
你只是在同一个查询,但在服务器端,之后,它应该工作正常 .
通过添加以下附加参数,基本上改变API头响应 .
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:*
但就安全性而言,这不是一个好的解决方案
你需要在你的php页面“login.php”的开头添加它
当我使用
Angular
将记录发布到Django REST
后端时,我遇到了这个问题 . 有时,这个问题没有特别的原因 . 仔细检查您的Django的错误消息,您将找到一个解决方案 .使用 addHeader 而不是使用 setHeader 方法,
上面的 ***** 将允许 access to all domains .
允许 access to specific domain only :
检查这个blog post .