enable cors in .htaccess - php

I have created a basic RESTful service with the SLIM PHP framework and now I'm trying to wire it up so that I can access the service from an Angular.js project. I have read that Angular supports CORS out of the box and all I needed to do was add this line: Header set Access-Control-Allow-Origin "*" to my .htaccess file.
I've done this and my REST application is still working (no 500 internal server error from a bad .htaccess) but when I try to test it from test-cors.org it is throwing an error.
Fired XHR event: loadstart
Fired XHR event: readystatechange
Fired XHR event: error
XHR status: 0
XHR status text:
Fired XHR event: loadend
My .htaccess file looks like this
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /index.php [QSA,L]
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
Is there something else I need to add to my .htaccess to get this to work properly or is there another way to enable CORS on my server?

Since I had everything being forwarded to index.php anyway I thought I would try setting the headers in PHP instead of the .htaccess file and it worked! YAY! Here's what I added to index.php for anyone else having this problem.
// Allow from any origin
if (isset($_SERVER['HTTP_ORIGIN'])) {
// should do a check here to match $_SERVER['HTTP_ORIGIN'] to a
// whitelist of safe domains
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']))
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
credit goes to slashingweapon for his answer on this question
Because I'm using Slim I added this route so that OPTIONS requests get a HTTP 200 response
// return HTTP 200 for HTTP OPTIONS requests
$app->map('/:x+', function($x) {
http_response_code(200);
})->via('OPTIONS');

Should't the .htaccess use add instead of set?
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"

This is what worked for me:
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

As in this answer Custom HTTP Header for a specific file you can use <File> to enable CORS for a single file with this code:
<Files "index.php">
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT"
</Files>
Instead of "*" you can put specific origin (protocol + domain+ optional port).

Will be work 100%, Apply in .htaccess:
# Enable cross domain access control
SetEnvIf Origin "^http(s)?://(.+\.)?(1xyz\.com|2xyz\.com)$" REQUEST_ORIGIN=$0
Header always set Access-Control-Allow-Origin %{REQUEST_ORIGIN}e env=REQUEST_ORIGIN
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header always set Access-Control-Allow-Headers "x-test-header, Origin, X-Requested-With, Content-Type, Accept"
# Force to request 200 for options
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]

It's look like you are using an old version of slim(2.x). You can just add following lines to .htaccess and don't need to do anything in PHP scripts.
# Enable cross domain access control
SetEnvIf Origin "^http(s)?://(.+\.)?(domain_one\.com|domain_two\.net)$" REQUEST_ORIGIN=$0
Header always set Access-Control-Allow-Origin %{REQUEST_ORIGIN}e env=REQUEST_ORIGIN
Header always set Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
Header always set Access-Control-Allow-Headers: Authorization
# Force to request 200 for options
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]

Thanks to Devin, I figured out the solution for my SLIM application with multi domain access.
In htaccess:
SetEnvIf Origin "http(s)?://(www\.)?(allowed.domain.one|allowed.domain.two)$" AccessControlAllowOrigin=$0$1
Header set Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Credentials true
in index.php
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
}
// instead of mapping:
$app->options('/(:x+)', function() use ($app) {
//...return correct headers...
$app->response->setStatus(200);
});

For ubuntu users:
You have to activate first the headers module by using the following command:
sudo a2enmod headers
Then restart apache by:
sudo service apache2 restart
Then add the following headers to your htaccess:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header set Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

I tried #abimelex solution, but in Slim 3.0, mapping the OPTIONS requests goes like:
$app = new \Slim\App();
$app->options('/books/{id}', function ($request, $response, $args) {
// Return response headers
});
https://www.slimframework.com/docs/objects/router.html#options-route

Related

Angular 8 with php and mysql database Cross-Origin Request Blocked:

I am trying to build a login and register with angular 8 platform,
with php and mysql database.
php and mysql uses localhost/ and angular 8 uses localhost:4200.
I am trying to send data to mysql database but there is a error message in the console:
Cross-Origin Request Blocked:
To communicate between localhost/ and localhost:4200 i used this code
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
#Set the headers for the restful api
Header always set Access-Control-Allow-Origin http://localhost:4200
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization,
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Access-Control-Allow-Origin"
Header always set Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
but still I am getting this error. Is there anybody to help me?
From enable cors in .htaccess (this question is a duplicate!) You need to use add instead of set. Remove all the rules and replace by:
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
The asterisk should be replaced by the correct domain in production mode.

Angular and XAMPP CORS Policy

I am trying to send some requests from my angular app to my local xampp server, but the requests are blocked due to CORS Policy.
I have already added following line to the httpd.conf file:
Header set Access-Control-Allow-Origin *
I have also added an .htaccess file to my htdocs folder with following content:
Header set Access-Control-Allow-Origin *
I have also added this to my php file:header("Access-Control-Allow-Origin: *"); but this had no impact as well.
My angular app runs on localhost:4200 and the xampp runs on localhost:80
I know allowing every origin is a great security issue, but it is only for testing purpose.
I think you need a few more headers from your server side, namely Access-Control-Allow-Methods and Access-Control-Allow-Headers.
header("Access-Control-Allow-Origin: http://localhost:4200");
header("Access-Control-Allow-Methods: GET,POST,PUT,OPTIONS");
header("Access-Control-Allow-Headers:*");
Try modifying your http.conf like this
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]

CORS problem with axios from a Vue app to a PHP API running on WAMP [duplicate]

This question already has answers here:
google storage vedio files cannot plays directly from localhost angular [duplicate]
(1 answer)
Disable CORS in Expres.io for socket.io calls
(1 answer)
Closed 2 years ago.
I have trouble making an XHR request with axios from a Vue app to a PHP API running on WAMP.
The error message is the following :
Access to XMLHttpRequest at 'http://localhost/myapp/api/test/1' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
As you can see, it's a problem with CORS. After some documentation, here is what I have been doing to fix it (still not working).
Axios call :
axios({
method: 'get',
url: 'http://localhost/myapp/api/test/1',
data: JSON.stringify({}),
headers: { 'Content-Type': 'application/json', },
crossdomain: true,
});
If I visit http://localhost/myapp/api/test/1 in my web browser, I got my response.
I attempted putting this line of code in my PHP API, in my entry point (index.php)
header('Access-Control-Allow-Origin: *');
I configured WAMP :
Changed httpd-vhosts.conf and httpd.conf
# Virtual Hosts
<VirtualHost *:80>
ServerName localhost
ServerAlias localhost
DocumentRoot "${INSTALL_DIR}/www"
<Directory "${INSTALL_DIR}/www/">
Options +Indexes +Includes +FollowSymLinks +MultiViews
Header set Access-Control-Allow-Origin "*"
AllowOverride All
Require local
</Directory>
</VirtualHost>
Activated the "headers_module" in apache's modules
Rebooted everything, cleared my cache, tried from another browser ...
Still not working, am I missing something ?
I use this at the top of my index.php file to fix CORS problems:
function cors() {
// Allow from any origin
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS");
header("Access-Control-Allow-Headers: Origin, Authorization, X-Requested-With, Content-Type, Accept");
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, PATCH, PUT, DELETE, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: Origin, Authorization, X-Requested-With, Content-Type, Accept");
exit(0);
}
}
cors();
Try this extension for cross origin.
https://chrome.google.com/webstore/detail/moesif-orign-cors-changer/digfbfaphojjndkpccljibejjbppifbc

WordPress No 'Access-Control-Allow-Origin' header is present on the requested resource

I am pulling posts from one WordPress website to another. Both websites are on same server. For pulling posts i am using jQuery.ajax with Rest API. But i am getting error message in console
Access to XMLHttpRequest at 'https://www.website1.com/wp-json/wp/v2/posts/?tags=4,198&per_page=24&offset=1&_embed' from origin 'https://website2.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
For this i have added following header
Header set Access-Control-Allow-Origin "*"
In .htaccess of both websites. Also i have used this
crossDomain: true,
In ajax. But still having error. Any help. Please
Just add below lines to .htaccess file and we should be good.
<ifmodule mod_headers.c="">
SetEnvIf Origin "^(.*\.domain\.com)$" ORIGIN_SUB_DOMAIN=$1
Header set Access-Control-Allow-Origin "%{ORIGIN_SUB_DOMAIN}e" env=ORIGIN_SUB_DOMAIN
Header set Access-Control-Allow-Methods: "*"
Header set Access-Control-Allow-Headers: "Origin, X-Requested-With, Content-Type, Accept, Authorization"
</ifmodule>

CORS with php (Wordpress)

I have relaunched my website with Wordpress.
Unfortunately, a couple of fonts are not being displayed neither in Chrome nor Firefox nor IE. I get the following error:
Access to Font at 'MY WORDPRESS FONTS URL' from origin 'http://w8qb4xj6s.homepage.t-online.de' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the
requested resource. Origin 'http://www.obstgut-auf-der-heide.de' is
therefore not allowed access.
This is probably because I've installed Wordpress in a subdirectory, but then "moved" it so the root by copying the index.php to the root (I want the new website to be displayed when requesting the home URL).
In order to fix the missing fonts, I've tried adding either of the following code to header.php and wp-blog-header.php:
header("Access-Control-Allow-Origin: *");
or
Header set Access-Control-Allow-Origin: *
Header set Access-Control-Allow-Headers: Content-Type, Depth,
User-Agent, X-File-Size, X-Requested-With, If-Modified-Since, X-File-
Name, Cache-Control
Header set Access-Control-Allow-Credentials: true
Header set Access-Control-Allow-Methods: OPTIONS, GET, POST
or
var invocation = new XMLHttpRequest();
var url = 'http://www.obstgut-auf-der-heide.de/';
function callOtherDomain(){
if(invocation) {
invocation.open('GET', url, true);
invocation.withCredentials = true;
invocation.onreadystatechange = handler;
invocation.send();
}
}
I've also replaced the "*" by the home-URL. Nothing worked. I'm very new to this whole matter and don't know much about php and stuff. But maybe one of you have any idea what else I could try to fix this?? I'd be super grateful!!!!
Thanks, Elena
The problem here seems to be that you previously had the fonts on the same domain as the WordPress installation. Now that fonts live on a different domain (and possibly different server), you need to set the Access-Control-Allow-Origin header on the server that is handling the fonts, not the one serving WordPress.
On Nginx it would be something like:
location ~ \.(eot|ttf|otf|woff)$ {
add_header Access-Control-Allow-Origin *;
}
On Apache's .htaccess it will be exactly as you did above, but you should restrict this header to font files:
AddType application/vnd.ms-fontobject .eot
AddType application/x-font-ttf .ttf
AddType application/x-font-opentype .otf
AddType application/font-woff .woff
<FilesMatch ".(eot|ttf|otf|woff)">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
I faced same issue Today and I am able to solve following link
https://thoughtsandstuff.com/wordpress-rest-api-cors-issues/
Add this to your WordPress function.php file and you should be set!
add_action('init', 'handle_preflight');
function handle_preflight() {
$origin = get_http_origin();
if ($origin === 'https://yourfrontenddomain') {
header("Access-Control-Allow-Origin: yourfrontenddomain");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE");
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Headers: Origin, X-Requested-With, X-WP-Nonce, Content-Type, Accept, Authorization');
if ('OPTIONS' == $_SERVER['REQUEST_METHOD']) {
status_header(200);
exit();
}
}
}
add_filter('rest_authentication_errors', 'rest_filter_incoming_connections');
function rest_filter_incoming_connections($errors) {
$request_server = $_SERVER['REMOTE_ADDR'];
$origin = get_http_origin();
if ($origin !== 'https://yourfrontenddomain') return new WP_Error('forbidden_access', $origin, array(
'status' => 403
));
return $errors;
}
I had the same problem but with icons may solution at the moment is like that:
Depending on your host service you should have a .htaccess file (if it's an Apache server) in your root directory. With a Wordpress installation it's content is like that:
# BEGIN WordPress
<IfModule mod_rewrite.c>
Header set Access-Control-Allow-Origin "*"
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
I added the line Header set Access-Control-Allow-Origin "*" and the CORS error was gone.

Categories