问题描述
我正在构建一个API,以激活和验证我的PHP脚本的有效安装, 但是我从来源“ http://domain.te”获得了对来自http://api.domain.te/requests/verify的“对XMLHttpRequest的访问”,这已被CORS策略阻止:没有“访问控制” -Allow-Origin'标头出现在请求的资源上” 控制台错误。
这是我的jQuery代码:
function verify() {
$.post(url+"requests/verify",{
domain: domain
},function(data) {
if (data.success === true) {
return true;
}
});
return false;
}
我已经阅读了类似的问题并尝试了所有建议,但似乎都没有用。
public function verify()
{
$data['success'] = false;
$data['status'] = 'error';
$data['message'] = 'An error occurred';
if ($this->actives_m->check($this->request->getPost("domain")??""))
{
$data['success'] = true;
$data['status'] = 'success';
$data['message'] = 'Product is Active!';
}
else
{
$data['message'] = 'Product is Inactive!';
}
$this->response->setHeader('Access-Control-Allow-Origin','*');
$this->response->setHeader('Access-Control-Allow-Methods','GET,POST');
return $this->response->setJSON($data);
}
我也尝试过在<?PHP
之后的脚本开头设置标头,但仍然无法正常工作。
我还尝试了内置的PHP header()
函数,如下所示:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET,POST');
我什至将我的JS修改为:
function verify() {
$.ajax({
url: url+"requests/verify",type: "POST",dataType: "JSON",data: {domain: domain},crossDomain: true,success: function(data) {
if (data.success === true) {
return true;
}
}
});
return false;
}
到目前为止,似乎没有任何工作,我应该从这里去哪里?
更新: 我意识到,如果我使用纯Javascript,例如:
const xhr = new XMLHttpRequest();
xhr.open('GET',url+"requests/verify");
xhr.onreadystatechange = function(data) {
if (data.success === true) {
return true;
}
}
xhr.send();
它可以按预期工作,但是我必须使用jQuery来保持我的代码统一,以备将来参考。
解决方法
正如您已经做过的那样,必须从接收服务器端获取CORS,因此我将 .htaccess 中的标头放在Apache站点中(如果使用其他服务器,请检查如何做):>
display
(在您的情况下,如果可以是多个未知域,则应为*)
Header set Access-Control-Allow-Origin "*"
(如果需要,也可以使用方法)
该标题上的信息和选项: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
您可以使用curl检查要发送的标题,它们出现了吗?
Header set Access-Control-Allow-Headers "Origin,X-Requested-With,Content-Type,Accept"
每当出现跨域问题时,都会有两条路线被点击。可以说,在您的示例中,您对“ http://api.domain.te/requests/verify”有GET请求,因此在使用GET请求访问服务器之前,它将与OPTIONS请求访问相同的URL。这将验证您的服务器是否允许跨源请求的API。
因此,在CI4路由中,您必须定义相同的URL或包含通配符以启用跨源请求。
以下是通配符请求的示例。
$routes->options('(:any)','Controller/options');
这条路线使用OPTIONS方法与任何路线匹配,并且有一个称为“选项”的方法来处理它。
此选项方法可以定义如下:
public function options($any)
{
return $this->response->setHeader('Access-Control-Allow-Origin','*') //for allow any domain,insecure
->setHeader('Access-Control-Allow-Headers','*') //for allow any headers,insecure
->setHeader('Access-Control-Allow-Methods','GET,POST,OPTIONS,PUT,DELETE') //method allowed
->setStatusCode(200); //status code
}
此方法本质上的作用是让浏览器知道跨域请求已被允许,其状态方法为GET,POST,PUT和DELETE。
浏览器点击此请求后,会将其定向到您的请求,该请求还应启用交叉源,如下所示:
$this->response->setContentType('application/json')->setJSON($response)->send()->setHeader('Access-Control-Allow-Origin','*');
参考:https://carminemilieni.it/2019/09/19/resolve-cors-and-corb-in-codeigniter-4/