How can I check if file exists in nginx? otherwise

2019-07-22 01:41发布

问题:

good day everyone,

In order to resize images on the fly, i have decided to use a service like Kraken or imgix.

My images will be displayed as so: site.com/img/path-to-img-s250x250.jpg and what i would like to achieve is: if the image path-to-img-s250x250.jpg exists, then i'll display it, and if not then run an nginx rewrite rule to resize the original image and save it.

Is this something possible or should i do the checks with PHP?

Also do you have any better ideas on how to better deal with resizing images on the fly?

Thanks a lot

location /img/ {
    try_files $uri @getImg @resize;
}

location @getImg{
    rewrite "img/(.*)/([a-z0-9]+)-([0-9]+)x([0-9]+).([0-9]{5}).(jpg|jpeg|png|gif|ico)$" /img/$1/$2-$3x$4.$6 break;
}

location @resize{
    rewrite "img/(.*)/([a-z0-9]+)-([0-9]+)x([0-9]+).([0-9]{5}).(jpg|jpeg|png|gif|ico)$" $scheme://$host/image?path=$1&file=$2&ext=$6&w=$3&h=$4 break;
}

and here is the image link: site.com/img/prods/1002/filename-200x200.12345.jpg

12345 is for the versioning

回答1:

You can use try_files to test for the existence of one or more files. See this document for details.

Use a regular expression location to capture the elements of the URI. Regular expression locations are evaluated in order, so there position within the configuration file may be significant. See this document for details.

If the final parameter of a try_files statement is a URI. it will generate an internal redirect.

For example:

location ~ "^/img/(.*)/([a-z0-9]+)-([0-9]+)x([0-9]+)\.([0-9]{5})\.(jpg|jpeg|png|gif|ico)$" {
    try_files $uri /img/$1/$2-$3x$4.$6 /image?path=$1&file=$2&ext=$6&w=$3&h=$4;
}

The above will not work on its own, as many PHP scripts use the originally requested URI (REQUEST_URI) to determine the route.

You can create a custom location to explicitly set the REQUEST_URI and SCRIPT_FILENAME parameters.

For example:

location = /image {
    include        fastcgi_param;
    fastcgi_pass   ...;
    fastcgi_param  SCRIPT_FILENAME  $document_root/index.php;
    fastcgi_param  REQUEST_URI      $uri$is_args$args;
}

Base this block on your existing code (the above is just a guess). We include the global configuration files first, then override SCRIPT_FILENAME and REQUEST_URI. I have assumed that index.php is handling the /image route.