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.
Related
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.
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]
I have a PHP application where I conditionally set the Access-Control-Allow-Origin header. I see the change reflected on my local setup and on the dev environment, but on the live site, the header is set as something else. The other headers that I set along with it keep their values, so it leads me to believe that the Access-Control-Allow-Origin header is being overwritten somewhere else.
I've checked the .htaccess files in my project and the apache virtual host configuration file for possible places the header could be overwritten. It was being set in the virtual host config file, but I commented it out and restarted apache, but the header is still being overwritten.
Is there any other place that I can check to see if the header is being overwritten?
Thanks in advance for your help!
Here is the requested PHP code snippet:
$origin=$front->getRequest()->getHeader('Origin');
if($origin && (preg_match('/http[s]{0,1}:\/\/' . $front->getRequest()->getHttpHost() . '$/', $origin))){
$front->getResponse()->setHeader('Access-Control-Allow-Origin', $origin);
$front->getResponse()->setHeader('Access-Control-Allow-Credentials', 'true');
}else{
//leave current value if there is no match
$front->getResponse()->setHeader('Access-Control-Allow-Origin', '*');
}
I'm pretty sure the header is being overwritten by something else because I can see the Access-Control-Allow-Credentials:true come through as expected, but Access-Control-Allow-Origin has a value of *.
I did some more digging and found this link to do the same in the .htaccess. I ended up adding the following:
SetEnvIf Origin "^http(s)?://(.+\.)?(www.example.com)$" origin_is=$0
Header set Access-Control-Allow-Origin %{origin_is}e env=origin_is
Header set Access-Control-Allow-Credentials true env=origin_is
You can set header from htaccess:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
Or from PHP:
header("access-control-allow-origin: *");
You can use:
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|font.css|css)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
to apply htaccess header for specified files.
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
I wrote a REST-ful API using Fat Free Framework in PHP, and am making a call using backbone.js. When I try and save a new Orders model my app makes a PUT request, and the server spits back a 406 error.
Request Method:PUT
Status Code:406 Not Acceptable
Request Headers
Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:174
Content-Type:application/json
Cookie:__utma=239804689.76636928.1286699220.1305666110.1325104376.94; __utmz=239804689.1325104376.94.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); PHPSESSID=935d2632fd0d12a1a0df4cb0f392eb5e
X-Requested-With:XMLHttpRequest
Request Payload
{"id":0,"customerId":0,"lastPage":"items","priceConfig":null,"items":null,"saveStatus":0,"savedAt":1326588395899,"name":null}
Response Headers
Connection:Keep-Alive
Content-Length:460
Content-Type:text/html; charset=iso-8859-1
Date:Sun, 15 Jan 2012 00:46:37 GMT
Keep-Alive:timeout=5, max=98
Server:Apache
My .htaccess file looks like this:
# Enable rewrite engine and route requests to framework
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L,QSA]
# Disable ETags
<IfModule mod_headers.c>
Header Unset ETag
FileETag none
</IfModule>
# Default expires header if none specified (stay in browser cache for 7 days)
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault A604800
</IfModule>
<IfModule mod_security.c>
SecFilterEngine Off
SecFilterScanPOST Off
</IfModule>
My website application works fine on my local server and only does this on my web server. Any ideas what is going wrong?
I came up with a workaround.
My believe my server is using mod_security2 to block PUT and DELETE requests. I am waiting to hear back from them, and mod_security2 can't be disabled in .htaccess files so there's nothing I can do.
Using "Script PUT /filename" in the .htaccess file was causing a 500 error: "Script not allowed here", I am not sure why, but I decided not to deal with having my web host reconfigured to handle PUT and DELETE.
To keep my API REST-ful, I left in the normal handling of PUT and DELETE, and added this to the POST handling:
function post() {
//if Backbone.emulateHTTP is true, emulate PUT
$data = json_decode(F3::get('REQBODY'), true);
$type = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']; //PUT, DELETE, POST
if ($type == 'PUT') {
$this->put();
return;
}
if ($type == 'DELETE') {
$this->delete();
return;
}
//handle normal POST here
}
If you set Backbone.emulateHTTP = true; it keeps the request method as POST and sends the X-HTTP-Method-Override as PUT or DELETE.
I like this because I can keep my REST-ful implementation intact, and just comment out the emulateHTTP code for when I publish to my webserver.