Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://myapp.local/myAppApi/V1/appLogin. This can be fixed by moving the resource to the same domain or enabling CORS.
Cross-origin resource sharing (CORS) is a technique that allow servers to serve resources to permitted origin domains by adding HTTP headers to the server who are respected from web browsers. Examples of practical use of CORS are cross-domain AJAX requests, or using fonts hosted on a subdomain.
Handling CORS requests properly is a tad more involved. Here is a function that will respond more fully (and properly).
/**
* An example CORS-compliant method. It will allow any GET, POST, or OPTIONS requests from any
* origin.
*
* In a production environment, you probably want to be more restrictive, but this gives you
* the general idea of what is involved. For the nitty-gritty low-down, read:
*
* - https://developer.mozilla.org/en/HTTP_access_control
* - https://fetch.spec.whatwg.org/#http-cors-protocol
*
*/
function cors() {
// Allow from any origin
if (isset($_SERVER['HTTP_ORIGIN'])) {
// Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one
// you want to allow, and if so:
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
// may also be using PUT, PATCH, HEAD etc
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}
echo "You have CORS!";
}
Check the HTTP_ORIGIN header against a list of approved origins.
If the origin isn't approved, then you should deny the request.
Please read the spec.
When a browser wants to execute a cross-site request it first confirms that this is okay with a "pre-flight" request to the URL. By allowing CORS you are telling the browser that responses from this URL can be shared with other domains.
CORS does not protect your server. CORS attempts to protect your users by telling browsers what the restrictions should be on sharing responses with other domains. Normally this kind of sharing is utterly forbidden, so CORS is a way to poke a hole in the browser's normal security policy. These holes should be as small as possible, so always check the HTTP_ORIGIN against some kind of internal list.
There are some dangers here, especially if the data the URL serves up is normally protected. You are effectively allowing browser content that originated on some other server to read (and possibly manipulate) data on your server.
If you are going to use CORS, please read the protocol carefully (it is quite small) and try to understand what you're doing. A reference URL is given in the code sample for that purpose.
It has been observed that the HTTP_ORIGIN header is insecure, and that is true. In fact, all HTTP headers are insecure to varying meanings of the term. Unless a header includes a verifiable signature/hmac, or the whole conversation is authenticated via TLS, headers are just "something the browser has told me".
In this case, the browser is saying "an object from domain X wants to get a response from this URL. Is that okay?" The point of CORS is to be able to answer, "yes I'll allow that".
I got the same error, and fixed it with the following PHP in my back-end script:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header("Access-Control-Allow-Headers: X-Requested-With");
Access-Control-Allow-Headers
does not allow *
as accepted value, see the Mozilla Documentation here.
Instead of the asterisk, you should send the accepted headers (first X-Requested-With
as the error says).
*
is now accepted is Access-Control-Allow-Headers
.
According to MDN Web Docs 2021:
The value
*
only counts as a special wildcard value for requests without credentials (requests without HTTP cookies or HTTP authentication information). In requests with credentials, it is treated as the literal header name*
without special semantics. Note that the Authorization header can't be wildcarded and always needs to be listed explicitly.
Many description internet-wide don't mention that specifying Access-Control-Allow-Origin
is not enough. Here is a complete example that works for me:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
header('Access-Control-Allow-Headers: token, Content-Type');
header('Access-Control-Max-Age: 1728000');
header('Content-Length: 0');
header('Content-Type: text/plain');
die();
}
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
$ret = [
'result' => 'OK',
];
print json_encode($ret);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With