我正在使用 .htaccess 来重写 url,并且我使用了 html 基本标记以使其工作。
现在,当我尝试发出 ajax 请求时,出现以下错误:
XMLHttpRequest 无法加载 http://www.example.com/login.php。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问来源“http://example.com”。
http://wordicious.com
与 http://www.wordicious.com/
是一个不同的域,因此是错误的。顺便说一句,如果它现在正在工作并自行恢复,您可能应该删除该问题。
使用 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
。
为什么会引发错误:
JavaScript 代码受 same-origin policy 限制,这意味着,从位于 www.example.com
的页面,您只能向位于完全相同域的服务发出 (AJAX) 请求,在这种情况下,完全是 { 2}(not example.com
- 没有 www
- 或 whatever.example.com
)。
在您的情况下,您的 Ajax 代码试图从位于 http://www.wordicious.com
的页面访问 http://wordicious.com
中的服务。
虽然非常相似,但它们不是同一个域。并且当它们不在同一个域中时,只有在目标的响应中包含 Access-Control-Allow-Origin
标头时,请求才会成功。
由于您在 http://wordicious.com
的页面/服务从未配置为显示此类标头,因此会显示该错误消息。
解决方案:
如前所述,源域(带有 JavaScript 的页面所在的位置)和目标域(JavaScript 试图到达的位置)域必须完全相同。
你的情况似乎是一个错字。看起来 http://wordicious.com
和 http://www.wordicious.com
实际上是同一个服务器/域。因此,要修复,请同样键入目标和来源:让您的 Ajax 代码请求页面/服务到 http://www.wordicious.com
而不是 http://wordicious.com
。 (可能相对放置目标 URL,如 '/login.php'
,不带域)。
更一般的说明:
如果问题不是像这个问题中的一个错字,解决方案是将 Access-Control-Allow-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”标头。 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 酒店搜索 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));
您只是在执行相同的查询,但在服务器端,之后,它应该可以正常工作。
您需要在您的 php 页面“login.php”的开头添加它
<?php header('Access-Control-Allow-Origin: *'); ?>
您必须将标题键/值放在选项方法响应中。例如,如果您在 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");
}
}
基本上通过添加以下附加参数来更改 API 标头响应。
访问控制允许凭据:true
访问控制允许来源:*
但这在安全性方面不是很好的解决方案
解决方法是使用在您的“源”主机上运行的反向代理并转发到您的目标服务器,例如 Fiddler:
链接在这里:http://docs.telerik.com/fiddler/configure-fiddler/tasks/usefiddlerasreverseproxy
或 Apache 反向代理...
将此添加到您的 PHP 文件或主控制器
header("Access-Control-Allow-Origin: http://localhost:9000");
header("Access-Control-Allow-Credentials: true");
通过 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}]]
请在 Javascript 中找到 XMLHTTPREQUEST 中用于设置请求标头的函数。
...
xmlHttp.setRequestHeader("Access-Control-Allow-Origin", "http://www.example.com");
...
</script>
参考:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader
不定期副业成功案例分享