【发布时间】:2022-01-23 02:13:32
【问题描述】:
所以我知道那里有很多 CORS 帖子,我只是在添加它们,但我找不到任何可以帮助我的答案。所以我正在构建一个依赖于我的 php api 的 angular 4 应用程序。在本地工作很好,当我使用app.example.com 的应用程序和api.example.com 的api 将它扔到域上时,我无法通过我的登录,因为我收到以下错误:
XMLHttpRequest 无法加载 http://api.example.com/Account/Login。 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://app.example.com” 访问。
我的 php 代码如下所示:
$http_origin = $_SERVER['HTTP_ORIGIN'];
$allowed_domains = array(
'http://example.com',
'https://example.com',
'http://app.example.com',
'https://app.example.com',
'http://www.example.com',
'https://www.example.com'
);
if (in_array(strtolower($http_origin), $allowed_domains))
{
// header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Origin: $http_origin");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400');
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Authorization, Content-Type,Accept, Origin");
exit(0);
}
我的 Angular 帖子如下所示:
public login(login: Login): Observable<LoginResponse> {
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
headers.append('Authorization', 'Basic ' + btoa(login.Username + ':' + login.Password));
return this.http.post(this.apiBaseUrl + '/Account/Login', "grant_type=client_credentials", { headers: headers })
.map(response => {
// code
});
}
如果我通过邮递员运行请求,这不会打扰 CORS,我会得到:
{ "error": "invalid_client", "error_description": "Client credentials were not found in the headers or body" }
我尝试将 origin 设置为 '*' 只是为了测试一下这是否是问题的核心,但它仍然以同样的方式失败。
编辑 只是从下面的信息更新。更改标题中的大小写没有效果,将代码从 if 语句中拉出也没有效果。
我通过告诉我的实时应用程序转到我的本地 api 来调试 php,并且 php 正在按预期工作。它正在设置标题并将其放入每个 if 语句中。
编辑镜头 2 我真的可以在这方面使用一些帮助,如果有人有任何想法,我将不胜感激。
编辑镜头 3 如果我在我的 .htaccess 而不是我的 php 中设置所有标题内容,它会让我通过。但是,现在我遇到了上面列出的错误,我在使用邮递员时总是遇到,但现在是在使用实际站点时。
{"error":"invalid_client","error_description":"Client credentials were not found in the headers or body"}
我的响应头是这样的
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:authorization, content-type, accept, origin
Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:*
一旦它工作,我会将它从 * 更改为仅我的域。但现在我将其保留为 *。
我请求的标题。
【问题讨论】:
-
从 if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { 中取出代码并检查发生了什么。
-
您可以通过在浏览器中检查网络选项卡来分享服务器响应的快照吗?
-
调试器中的响应选项卡是空白的,但这是标题 -- 响应:
Allow:POST,OPTIONS,GET,HEAD,TRACE Connection:keep-alive Content-Length:0 Content-Type:text/plain Date:Sun, 11 Jun 2017 02:41:43 GMT Keep-Alive:timeout=30 Server:Apache/2请求:Accept:*/* Accept-Encoding:gzip, deflate Accept-Language:en-US,en;q=0.8,ca;q=0.6 Access-Control-Request-Headers:authorization Access-Control-Request-Method:POST Connection:keep-alive Host:api.example.com Origin:http://app.example.com Referer:http://app.example.com/login -
您服务器上的
$http_origin是什么?您发布的响应标头上没有Access-Control-Allow-Origin,这解释了为什么您的浏览器会大惊小怪。实际上,您的任何标头似乎都没有被发送,因此我什至认为这些if语句中的任何一个都不是真的。拥有一个基于$_SERVER['http_origin']的动态Access-Control-Allow-Origin有点奇怪。您应该考虑在每个请求中发送您接受的实际域,或者将其设置为环境设置(以避免对域进行硬编码) -
@Nieminen — 如果代码在您使用不同的服务器时跨源工作,则表明问题不在于您的代码。例如,您可能在服务器上有某种反向代理,它会去除 Access-Control-Allow-Origin 标头。
标签: php angular cors preflight