php 返回 Access-Control-Allow-Origin 请求头,实现 ajax 异步请求跨域资源共享
问题描述
在当前域名 http://test.com
下的页面,使用 Jquery 的 .ajax()
异步请求另一个域名 http://app.com
。
$.ajax({
url: "http://app.com/index.php",
data: {test: "test"},
dataType: "json",
method: "post",
success: function() {
console.log("success");
},
error: function() {
console.log("error");
}
});
浏览器控制台报错了。
Access to XMLHttpRequest at 'http://app.com/index.php' from origin 'http://test.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
POST http://app.com/index.php net::ERR_FAILED
问题解决
浏览器基于 同源策略(same-origin policy),会阻止不同域的异步请求。除非被请求的域名返回 Access-Control-Allow-Origin
请求头,允许跨域访问。我们先认识一下请求头 Origin。
1. 了解 Http 请求头 Origin
Http 的 Headers Origin ,指示了请求来自于哪个站点。如果一个异步 ajax 访问的 url,不是当前域名,浏览器在发送请求的时候,会带上 Origin 的请求头。Origin 的格式是:
Origin: <scheme> "://" <host> [ ":" <port> ]
以下是一个异步请求的示例,原站点的 url 是 http://test.com/test/cors.html
,请求 http://app.com/index.php
,浏览器自动加上 Origin 请求头 http://test.com
,Google Chrome 浏览器的网络截图如下。
2. PHP 设置跨域 Access-Control-Allow-Origin 请求头
上面说到的 Origin 请求头的值,与 Access-Control-Allow-Origin
请求头的值其实是一致的。
2.1 匹配一个域名
返回一个域名的请求头,格式如:Access-Control-Allow-Origin: http://test.com
if (isset($_SERVER["HTTP_ORIGIN"]) && $_SERVER["HTTP_ORIGIN"] == "http://test.com") {
header("Access-Control-Allow-Origin: " . $_SERVER["HTTP_ORIGIN"]);
}
2.2 动态匹配多个域名
http 回应头 Response Headers,每次只能返回一个Access-Control-Allow-Origin
,即只能一个域名,可以通过 PHP 动态处理,使用 in_array
或者 preg_match
等方法。
$arr = ["http://test.com", "http://baidu.com"];
if (isset($_SERVER["HTTP_ORIGIN"]) && in_array($_SERVER["HTTP_ORIGIN"], $arr)) {
header("Access-Control-Allow-Origin: " . $_SERVER["HTTP_ORIGIN"]);
}
2.3 匹配所有域名
返回 * 号,匹配所有域名,格式如:Access-Control-Allow-Origin: *
header("Access-Control-Allow-Origin: *");
非特殊说明,本网站所有文章均为原创。如若转载,请注明出处:https://mip.cpming.top/p/php-cors