Home > Back-end >  Why nginx add_headers doesn't work properly?
Why nginx add_headers doesn't work properly?

Time:06-03

I'm using Nginx as a web server. This is my nginx.conf file:

server {

    listen 80;

    root /usr/share/nginx/html;
    index index.html index.htm;

    location ^~ /start/ {
        add_header 'Cross-Origin-Embedder-Policy' 'require-corp';
        add_header 'Cross-Origin-Opener-Policy' 'same-origin';
        try_files $uri $uri/ /index.html;
    }

    location / {
        try_files $uri $uri/ /index.html;
    }
}

When I open this link on the browser, I don't see the header in the network tab in the response headers section: https://example.com/start/629852d359d2a400034698a2

enter image description here

CodePudding user response:

Actually add_header directive works properly. It happens because most probably there are no /usr/share/nginx/html/start/629852d359d2a400034698a2 file or directory on your server, so request gets rewritten to /index.html according to the last try_files directive parameter, which in turn being processed by your location / { ... } (since that new URI does not start with a /start/ prefix), and that location does not set any additional headers.


Generally, if those /start/-prefixed URIs could be either internal application routes or external assets links, this would be possible to solve using the map block to evaluate required headers values:

map $uri $add_policies {
    ~^/start/  1;
    # default value will be an empty string, unless specified explicitly
}
map $add_policies $embedder_policy {
    1  require-corp;
}
map $add_policies $opener_policy {
    1  same-origin;
}
server {
    ...
    location / {
        add_header Cross-Origin-Embedder-Policy $embedder_policy;
        add_header Cross-Origin-Opener-Policy $origin_policy;
        try_files $uri $uri/ /index.html;
    }
}

This solution is based on the add_header behavior, which is not to add the specified header to the response at all if the provided value is an empty string.

However, if you know for sure the URIs where those headers should be added are an app routes rather than links to physically existing files, you have one more option:

server {
    ...
    location ^~ /start/ {
        set $embedder_policy require-corp;
        set $origin_policy same-origin;
        rewrite ^ /index.html last;
    }
    location / {
        add_header Cross-Origin-Embedder-Policy $embedder_policy;
        add_header Cross-Origin-Opener-Policy $origin_policy;
        try_files $uri $uri/ /index.html;
    }
}

This solution should be somewhat more performant since it does not require (some kind of expensive) PCRE library call to perform the regex matching operation.

  • Related