CORS: PHP: Response to preflight request failed. I allow origin
P粉642920522
2023-08-24 18:24:56
<p>So I know there are a lot of CORS posts out there and I'm just adding them but I can't find any answers that can help me. So I'm building an Angular 4 application that relies on my php api. Works locally no problem, when I throw it on the domain with the app at <code>app.example.com</code> and the api at <code>api.example.com</code> I am unable to pass my login as I get the following error: </p>
<blockquote>
<p>XMLHttpRequest cannot load http://api.example.com/Account/Login.
Response to preflight request failed access control check: No
'Access-Control-Allow-Origin' header present in request
resource. So source "http://app.example.com" is not allowed
access.</p>
</blockquote>
<p>我的 php 代码如下所示:</p>
<pre class="brush:php;toolbar:false;">$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);
}</pre>
<p>我的 Angular 帖子如下所示:</p>
<pre class="brush:php;toolbar:false;">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
});
}</pre>
<p>如果我通过邮递员运行请求(这不会影响 CORS),我会得到:</p>
<pre class="brush:php;toolbar:false;">{ "error": "invalid_client", "error_description": "Client credentials were not found in the headers or body" }</pre>
<p>我尝试将 origin 设置为 '<code>*</code>' 只是为了测试并查看这是否是问题的核心,但它仍然以同样的方式失败。</p>
<p><strong><em>编辑</em></strong>
只是根据以下信息进行更新。更改标头中的大小写没有任何效果,并且从 if 语句中提取代码也没有任何效果。</p>
<p>我通过告诉我的实时应用程序转到本地 api 来调试 php,并且 php 正在按预期工作。它设置标头并将其放入每个 if 语句中。</p>
<p><strong><em>编辑镜头 2</em></strong>
我确实需要一些帮助,如果有人有任何想法,我将非常感激。</p>
<p><strong><em>Edit Shot 3</em></strong>
If I set all the header stuff in .htaccess instead of php it lets me pass. However, now I'm stuck with the error listed above, which is the error I always get when using Postman, but now when using the actual website. </p>
<p><code>{"error":"invalid_client","error_description":"Client credentials not found in header or body"}</code></p>
<p>My response headers look like this</p>
<pre class="brush:php;toolbar:false;">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:*</pre>
<p>Once it's working I'll change it from * to just my domain. But now I leave it as *. </p>
<p><strong>My header upon request. </strong></p>
In my similar case, Angular frontend and Php backend helped with the code below. First I send a header:
After them I can ignore option requests:
This approach helped me handle "post" and "delete" embedded request methods in Angular.
Well, I had a similar problem recently and I solved it all on the backend only, without the .htaccess stuff.
When the browser sends a cross-server request, it first sends an OPTIONS request to ensure that it is valid and that a "real" request can be sent. The "real" request is sent when it gets a correct and valid response from OPTIONS.
Now, for both requests to the backend, you need to make sure the correct headers are returned: content-type, allow-origin, allow-headers, etc...
Ensure that in the OPTIONS request on the backend, the application returns the header and returns the response instead of continuing the full flow of the application.
In a "real" request you should return the correct headers and regular response body.
Example:
Things to remember:
If you use: "Access-Control-Allow-Credentials" = true Make sure "Access-Control-Allow-Origin" is not "*", it must be set to the correct domain! (A lot of blood was shed here :/)
Define the allow headers you will get in "Access-Control-Allow-Headers" If you don't define them, the request will fail