6
votes

For my sites I typically have two server{} blocks: one serves the site, and the other serves static content for that site from a different domain. Because the favicon.ico file is always asked for from the primary domain instead of the static domain, I have to handle that specific file in the site's server{} block rather than the static file block.

When a favicon.ico file is not found, Nginx returns my define 404 error page, as well as the 404 HTTP status code. However, I don't want to send those bits for my pretty 404 page. I want to send a totally empty response with a 204 status code. Below is what I tried, however it does not work. Is there a correct way to do this? The idea being that a 204 would indicate a found file, however a totally blank image.

Also, is my attempt to save bits actually a bad idea? If, in fact, returning 204 instead of 404 is a bad idea, is there a more elegant way to return an empty 404 page without creating a new-and-actually-empty file and setting that as the error_page directive inside that location block?

server {
    ...


    error_page  404          /../static/404.html;

    location @return_204 {
        return  204;
    }

    # Case-insensitive matching of .txt and .xml files.
    # (Example: robots.txt, crossdomain.xml, and sitemap.xml)
    location ~* \.(txt|xml)$ {
        try_files  $uri /../static/$uri;
    }

    location = /favicon.ico {
        log_not_found  off;
        error_page     404 = @return_204;

        try_files      $uri /../static/$uri;
    }

    ...
}
3

3 Answers

10
votes

I think this is what you're looking for:

location = /favicon.ico {
         try_files $uri = 204;
}

It will try to find the file at the URI or 204 as fallback. Here's the relevant documentation.

2
votes

A simple

location /favicon.ico { return 204; }

would be the easiest.

0
votes

The important bit is that the = and the HTTP status Code need to be one word and there must not be any space between. If you leave a space between, your error.log will fill quickly as 95% of all requests have a favicon.ico of some sort.

The following should be saved for reusability and just included where necessary.

# (i) No need to log presence or absence.
location = /favicon.ico {
  access_log     off;
  log_not_found  off;
  try_files      $uri  =204;
}