How to fix CORS headers in a single page application
What is a Preflight request?
# No preflight request will be sent here, the domains are the same (localhost:8000) http://localhost:8000 -> GET http://localhost:8000/api/resources # A preflight request will be sent here, the domains are the different (localhost:4200, localhost:8000) http://localhost:4200 -> GET http://localhost:8000/api/resources
When the domain differs, the browser will send an OPTIONS request before it sends the GET request. This OPTIONS request is simply there for the browser to ask the server if it can request this data. So if the server response with some explanatory headers and a 200 OK response, the browser will send the GET request and your application will have the data it needs.
How to solve this situation?
Solving this situation is quite simple: you just have to add headers to your response indicating what the browser is allowed to request and what not. Below will follow a few examples that you can copy/paste, be mindful how much you want to allow the browser to do though.
This section contains the settings you should use for Nginx, Apache will be further down. For this to work on Nginx, we'll make use of the add_header directive: Documentation can be found here
Allow all requests
# Allow all domains to request data add_header Access-Control-Allow-Origin *; # Allow all request methods (POST, GET, OPTIONS, PUT, PATCH, DELETE, HEAD) add_header Access-Control-Allow-Methods *; # Allow all request headers sent from the client add_header Access-Control-Allow-Headers *; # Cache all of these permissions for 86400 seconds (1 day) add_header Access-Control-Max-Age 86400;
Allow all requests from certain domains
# Allow http://localhost:4200 to request data add_header Access-Control-Allow-Origin http://localhost:4200; add_header Access-Control-Allow-Methods *; add_header Access-Control-Allow-Headers *; add_header Access-Control-Max-Age 86400;
Allow certain request types to be made
add_header Access-Control-Allow-Origin *; # Allow GET and HEAD requests to be made add_header Access-Control-Allow-Methods GET, HEAD; add_header Access-Control-Allow-Headers *; add_header Access-Control-Max-Age 86400;
Allow certain headers to be sent
add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods *; # Allow only the Authorization and Content-Type headers to be sent add_header Access-Control-Allow-Headers Authorization, Content-Type; add_header Access-Control-Max-Age 86400;
The same headers used in the section for Nginx will work in this section, you'll just have to implement it slightly differently. You can place them in a .htaccess file or straight into the Apache site configuration or global configuration.
<IfModule mod_headers.c> Header add Access-Control-Allow-Origin * Header add Access-Control-Allow-Methods * Header add Access-Control-Allow-Headers * Header add Access-Control-Max-Age * </IfModule>
As you can see, you will need to enable the headers module for Apache if this hasn't been done already.
I hope this post helped solve the problem, I know I got stuck with this for a few hours before I found this seemingly simple solution. If you have any other questions or comments, you can send them to me on Twitter.Posted on: September 27th, 2019