I discovered this problem when implementing the CDN feature on my website, as it is hosted on another subdomain (cdn.domain.com), the problem isn't visible on production as the CDN URL is hosted under the same domain (as a subdomain). But, in my local environment, I decided to use 2 different TLDs (top-level domain) for the app and the CDN. When I tried to access some resources from the local CDN, the following message appeared:
Access to Font at 'http://cdnmydomain/assets/fonts/font-awesome/webfonts/fa-solid-900.ttf' from origin 'http://mydomain' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
In my case, I do have the 2 domains as aliases on the hosts file of Windows:
# Copyright (c) 1993-2009 Microsoft Corp.
# C:\Windows\System32\drivers\etc\hosts
# Points to the localhost
127.0.0.1 mydomain
127.0.0.2 cdnofmydomain
The local IP is targeted through XAMPP, with an Apache virtual host that looks like this (cdnofmydomain):
<VirtualHost 127.0.0.2:80>
DocumentRoot "C:/xampp/htdocs/myproject/static"
DirectoryIndex index.php
<Directory "C:/xampp/htdocs/myproject/static">
AllowOverride All
Order Allow,Deny
Allow from All
</Directory>
</VirtualHost>
It simply serves the files in the c:/xampp/htdocs/myproject/static
directory. The solution, to allow mydomain to access the content of the other domain, it would be simply necessary to add the following instruction inside the Directory block of the virtual host:
Header Set Access-Control-Allow-Origin "*"
With this instruction, you're basically adding the Access-Control-Allow-Origin response header to every requests indicating that the response can be shared from the given origin. In this case, *
means allow access from anywhere. The virtual host with the instruction looks like this:
<VirtualHost 127.0.0.2:80>
DocumentRoot "C:/xampp/htdocs/myproject/static"
DirectoryIndex index.php
<Directory "C:/xampp/htdocs/myproject/static">
AllowOverride All
Order Allow,Deny
Allow from All
# Allow the access to the static domain from anywhere
# Note: in production this isn't ideal, just for local domains, testing purposes
Header Set Access-Control-Allow-Origin "*"
</Directory>
</VirtualHost>
As I said, this works great for the local environment, however, if you decide to implement such a thing in some kind of production server, it would be better to allow access from specific domains and not from everywhere, for example, to grant access to a specific domain only:
Header Set Access-Control-Allow-Origin "http://mydomain"
Grant access from multiple domains
As there can be only one CRS domain in the Access-Control-Allow-Origin
header, if you need to grant access from specific domains you may use the following trick:
SetEnvIf Origin "http(s)?://(www\.)?(domain1.com|domain2.com|subdomain.domain3.com)$" AccessControlAllowOrigin=$0
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
With this instruction, we are creating an environment variable that will be assigned only if the origin matches with the given regular expression, where you can replace the domains that you need to allow. Inside a virtual host, it looks like this:
<VirtualHost 127.0.0.2:80>
DocumentRoot "C:/xampp/htdocs/myproject/static"
DirectoryIndex index.php
<Directory "C:/xampp/htdocs/myproject/static">
AllowOverride All
Order Allow,Deny
Allow from All
SetEnvIf Origin "http(s)?://(www\.)?(domain1.com|domain2.com|subdomain.domain3.com)$" AccessControlAllowOrigin=$0
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
</Directory>
</VirtualHost>
Happy coding ❤️!