How to allow CORS on NGINX - nginx

So I want my domain scanner-api.local to accept file sent from mobile device/web apps .
I was getting
following error
MLHttpRequest cannot load http://scanner-api.local/upload. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access.
I tried to add following in my Nginx server but its not working , Nginx is crashing
code
server {
listen 80;
listen [::]:80;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/stock_scan_api/public/;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name scanner-api.local;
#location / {
# # First attempt to serve request as file, then
# # as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
#}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ /index.php?$query_string;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
include snippets/fastcgi-php.conf;
# With php7.0-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php7.0-fpm:
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
}
What could be the error in this ?

Try removing the single quotes surrounding the header and value like:
add_header Access-Control-Allow-Origin *;

Related

Nginx with auth_request_module to reverse proxied app throws CORS errors

I am developing a nginx server to work as a reverse proxy to a local webapp only when user is authenticated.
Here is my nginx myconfiguration.conf flie inside etc/nginx/sites-enabled/:
# Proxy Server to back-end site
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name internal.example.com;
# Internal web application
location / {
auth_request /aut;
error_page 401 = #error401;
proxy_pass http://192.168.1.13:8080;
}
# Autentication application
location = /aut {
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_pass http://192.168.1.130:8080/Autentication/Auth;
}
# Redirect to login site
location #error401 {
return 302 http://example.com/Autentication/login;
}
}
# Proxy server to Login site
server {
listen 80;
listen [::]:80;
server_name example.com;
# Internal web application for login
location / {
proxy_pass http://192.168.1.130:8080;
}
}
If users requests are authenticated through the auth_request /aut; everithing works great, but if we force the auth_request (on our auth api) to answer 'HTTP error 401' we slip into 2 different situations:
A) if the user refresh the page, everithing works: it means that the request do not pass the authorization and the client is redirected to our login page http://example.com/Autentication/login
B) if the user tries to fetch data from an api using javascript we receive this 3 errors in the browser console:
ERROR .1)
Access to XMLHttpRequest at 'http://example.com/Autentication'
(redirected from 'http://internal.example.com/TestServer/servlet')
from origin 'http://internal.example.com' has been blocked by CORS policy:
Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response
ERROR 2)
Access to XMLHttpRequest at 'http://example.com/Autentication'
(redirected from 'http://internal.example.com/page.html')
from origin 'http://internal.example.com/' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
ERROR 3)
Access to XMLHttpRequest at 'http://example.com/Autentication'
(redirected from 'http://internal.example.com/TestServer/servlets)
from origin 'http://internal.example.com' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
We tried, as suggested here, to add this configurations in our nginx myconfiguration.conf inside the location block but it didn't solved our problem:
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
After few days of testing some change here and there I SOLVED the problem:
No configuration needed on tomcat server (i mean no cors headers handled on tomcat server).
What i changed and was enough to let the whole infrastructure work was the myconfig.conf file on NGINX.
Here is the correct myconfig.conf:
# SERVER PROXY INTERNAL (can access only when auth_request is passed)----------------------------------------
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name internal.example.com;
# Proxy to internal tomcat with auth_request to /provaut
location / {
auth_request /prova_aut;
error_page 401 = #error401;
proxy_pass http://192.168.1.13:8080;
}
location = /prova_aut {
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_pass http://192.168.1.130:8080/Auth;
}
# Redirect to LOGIN
location #error401 {
return 302 http://example.com/Login;
}
}
# SERVER PROXY FOR LOGIN AND AUTH TOMCAT'S APP --------------------------
server {
listen 80;
listen [::]:80;
server_name example.com;
access_log /var/log/nginx/reverse-access.log;
error_log /var/log/nginx/reverse-error.log;
# Proxy to Authentication_app's tomcat
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'http://internal.example.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' 'http://internal.example.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range,Access-Control-Allow-Origin,Access-Control-Allow-Credentials' always;
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' 'http://internal.example.com' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range,Access-Control-Allow-Origin,Access-Control-Allow-Credentials' always;
}
proxy_pass http://192.168.1.130:8080;
}
}
What really made the trick was adding the two lines below in the /location block of the Login/Auth server
'Access-Control-Allow-Origin' 'http://internal.example.com' always;
and
'Access-Control-Allow-Credentials' 'true' always;
I Really hope this can help someone else ;)

NGINX + Vue HTML mode config giving 404

I have a Vue app running inside an nginx:alpine container with a custom nginx config to deal with browser navigation (Vue Router's html mode).
The problem is that any path other than the root (/) is giving 404's, with error messages like:
2018/11/25 07:56:13 [error] 7#7: *2 open() "/usr/share/nginx/html/home" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /home HTTP/1.1", host: "localhost:4000"
I'm using a custom nginx config file that looks like this:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}
}
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
# Some basic cache-control for static files to be sent to the browser
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
is there something wrong with my nginx.conf?
There are issues regarding using if inside a location block.
The try_files statement is not executed when the if ($request_method = 'GET') block is selected to process the request.
You can fix the problem by replacing the try_files statement with another if statement.
For example:
location / {
if (!-e $request_filename) { rewrite ^ /index.html last; }
if ($request_method = 'OPTIONS') { ... }
if ($request_method = 'POST') { ... }
if ($request_method = 'GET') { ... }
}

NGINX Enable CORS for a Google Places API call

I would like to enable CORS for Google Places API in order to call it from an Ionic 2 app with a WkWebView.
I am doing this in my nginx default config:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name _;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Nginx doesn't support nested If statements, so we
# concatenate compound conditions on the $cors variable
# and process later
# If request comes from allowed subdomain
# (*.googleapis.com) then we enable CORS
if ($http_origin ~* (https?://.*\.googleapis\.com(:[0-9]+)?$)) {
set $cors "1";
}
# OPTIONS indicates a CORS pre-flight request
if ($request_method = 'OPTIONS') {
set $cors "${cors}o";
}
# Append CORS headers to any request from
# allowed CORS domain, except OPTIONS
if ($cors = "1") {
more_set_headers 'Access-Control-Allow-Origin: $http_origin' always;
more_set_headers 'Access-Control-Allow-Credentials: true' always;
proxy_pass http://111.111.111.111:80;
}
# OPTIONS (pre-flight) request from allowed
# CORS domain. return response directly
if ($cors = "1o") {
more_set_headers 'Access-Control-Allow-Origin: $http_origin';
more_set_headers 'Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE';
more_set_headers 'Access-Control-Allow-Credentials: true';
more_set_headers 'Access-Control-Allow-Headers: Origin,Content-Type,Accept';
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
# Requests from non-allowed CORS domains
proxy_pass http://111.111.111.111:80;
}
}
But I am geeting a 502 Bad Gateway everytime I call:
http://111.111.111.111/maps/api/place/textsearch/json?key=APIKEY&query=starbucks
Any help, please?
Ok, I've found my mystake, proxy_pass should redirect to google not to my server:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name _;
#location / {
# # First attempt to serve request as file, then
# # as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
#}
location / {
proxy_pass https://maps.googleapis.com;
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST,GET,OPTIONS' always;
#preflight request
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' '1728000';
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' '0';
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'POST,GET,OPTIONS' always;
return 204;
}
}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}

Nginx configuration for enabling CORS

I am following the reference trying to have my nginx
accept CORS.
http://enable-cors.org/server_nginx.html
But no matter how i config my /etc/nginx/site-enable/default as following.
It just doesn't work. Is anything wrong about my configuration?
Thanks.
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html index.htm;
# Make site accessible from http://localhost/
server_name localhost;
#add_header Access-Control-Allow-Origin *; # < this is the needed header
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
#try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
#
# Om nom nom cookies
#
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
}
The Nginx CORS-Filter only gets triggered when all the headers you send within your requests are propagated in the allowed-headers field. Once you send only one header which is not mentioned in this section, the CORS-Filter will simply do nothing. Did you check your request headers?
In addition, your configuration will not work with PUT-Requests. Which type of requests do you send? Did you check the Response-headers?
Try to set ipv6only=off;

nginx add_header not working

I am having an intriguing problem where whenever I use add_header in my virtual host configuration on an ubuntu server running nginx with PHP and php-fpm it simply doesn't work and I have no idea what I am doing wrong. Here is my config file:
server {
listen 80; ## listen for ipv4; this line is default and implied
#listen [::]:80 default ipv6only=on; ## listen for ipv6
root /var/www/example.com/webroot/;
index index.html index.htm index.php;
# Make site accessible from http://www.example.com/
server_name www.example.com;
# max request size
client_max_body_size 20m;
# enable gzip compression
gzip on;
gzip_static on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header PS 1
location / {
# First attempt to serve request as file, then
# as directory, then fall back to index.html
try_files $uri $uri/ /index.php?$query_string;
# Uncomment to enable naxsi on this location
# include /etc/nginx/naxsi.rules
}
location ~* \.(css|js|asf|asx|wax|wmv|wmx|avi|bmp|class|divx|doc|docx|eot|exe|gif|gz|gzip|ico|jpg|jpeg|jpe|mdb|mid|midi|mov|qt|mp3|m4a|mp4|m4v|mpeg|mpg|mpe|mpp|odb|odc|odf|odg|odp|ods|odt|ogg|ogv|$
# 1 year -> 31536000
expires 500s;
access_log off;
log_not_found off;
add_header Pragma public;
add_header Cache-Control "max-age=31536000, public";
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
# With php5-cgi alone:
#fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
fastcgi_pass unix:/var/run/example.sock;
fastcgi_index index.php?$query_string;
include fastcgi_params;
# instead I want to get the value from Origin request header
}
# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
error_page 403 /403/;
}
server {
listen 80;
server_name example.com;
rewrite ^ http://www.example.com$request_uri? permanent;
}
I've tried adding the headers to the other location sections but the result is the same.
Any help appreciated!!
There were two issues for me.
One is that nginx only processes the last add_header it spots down a tree. So if you have an add_header in the server context, then another in the location nested context, it will only process the add_header directive inside the location context. Only the deepest context.
From the NGINX docs on add_header:
There could be several add_header directives. These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level.
Second issue was that the location / {} block I had in place was actually sending nginx to the other location ~* (\.php)$ block (because it would repath all requests through index.php, and that actually makes nginx process this php block). So, my add_header directives inside the first location directive were useless, and it started working after I put all the directives I needed inside the php location directive.
Finally, here's my working configuration to allow CORS in the context of an MVC framework called Laravel (you could change this easily to fit any PHP framework that has index.php as a single entry point for all requests).
server {
root /path/to/app/public;
index index.php;
server_name test.dev;
# redirection to index.php
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
# With php5-fpm:
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
# cors configuration
# whitelist of allowed domains, via a regular expression
# if ($http_origin ~* (http://localhost(:[0-9]+)?)) {
if ($http_origin ~* .*) { # yeah, for local development. tailor your regex as needed
set $cors "true";
}
# apparently, the following three if statements create a flag for "compound conditions"
if ($request_method = OPTIONS) {
set $cors "${cors}options";
}
if ($request_method = GET) {
set $cors "${cors}get";
}
if ($request_method = POST) {
set $cors "${cors}post";
}
# now process the flag
if ($cors = 'trueget') {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
}
if ($cors = 'truepost') {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
}
if ($cors = 'trueoptions') {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
}
error_log /var/log/nginx/test.dev.error.log;
access_log /var/log/nginx/test.dev.access.log;
}
The gist for the above is at: https://gist.github.com/adityamenon/6753574
I had the issue of not getting the response header due to the response code not within the allowed range, unless you specify the "always" keyword after the header value.
From the official docs:
Adds the specified field to a response header provided that the response code equals 200, 201, 204, 206, 301, 302, 303, 304, 307, or 308. The value can contain variables.
When I test the above add_header settings with:
# nginx -t && service nginx reload
I get
nginx: [emerg] directive "add_header" is not terminated by ";" in
/etc/nginx/enabled-sites/example.com.conf:21
nginx: configuration file /etc/nginx/nginx.conf test failed
So the complain is reagarding this line:
add_header PS 1
missing the semi-colon (;)
To test the headers I like to use
# curl -I http://example.com
According to the ngx_http_headers_module manual
syntax: add_header name value;
default: —
context: http, server, location, if in location
I further tried
add_header X-test-A 1;
add_header "X-test-B" "2";
add_header 'X-test-C' '3';
in the context of http, server and location, but it only showed up in the server context.
Firstly, let me say that after looking around the web, I found this answer popping up everywhere:
location ~* \.(eot|ttf|woff|woff2)$ {
add_header Access-Control-Allow-Origin *;
}
However, I have decided to answer this question with a separate answer as I only managed to get this particular solution working after putting in about ten more hours looking for a solution.
It seems that Nginx doesn't define any [correct] font MIME types by default. By following this tuorial I found I could add the following:
application/x-font-ttf ttc ttf;
application/x-font-otf otf;
application/font-woff woff;
application/font-woff2 woff2;
application/vnd.ms-fontobject eot;
To my etc/nginx/mime.types file. As stated, the above solution then worked. Obviously, this answer is aimed at sharing fonts but it's worth noting that the MIME types may not be defined in Nginx.
Evidently the add_header inheritance quirk/gotcha applies to the upstream layer as well.
I had a script pre-authorizing requests meant for another service, and was therefore returning all of the headers from the other service.
Once I started adding an 'Access-Control-Allow-Origin' entry along with these relayed headers, the browser would actually get the entry and allow the request.
I don't think it works properly by reloading ==> nginx -s reload
When I used add_header and then reloaded, nothing changed in response.
But when I made a deliberate error and saw a 404 error on the client side,
and then fixed my deliberate error and reloaded again, Add_header worked.
What does your nginx error log say?
Do you know which add_header lines are breaking the configuration? If not, comment them all out then enable them 1 by 1, reloading nginx to see which one(s) is/are the problem. I would begin by commenting out the block:
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header PS 1
The problem could be that you're setting headers not supported by the core httpHeaders module. Installing the NginxHttpHeadersMoreModule may be helpful.
Also, try replacing the two add_header lines int the location ~* \... with the following:
add_header Pragma '';
add_header Cache-Control 'public, max-age=31536000'
Is there a reason you have the gzip configuration here and not in your global nginx.conf?
It turns out that trying to update nginx to the newest version was causing this. I had tried previously to reinstall which seemed to reinstall it correctly but actually Ubuntu wasn't properly removing nginx. So all I had to do is reinstall Ubuntu server and install everything anew using just the standard ubuntu repositories.

Resources