Introduction#
Dealing with nginx is quite common, and I often encounter 404 issues that require me to look up information every time to come up with a solution. This time, I will summarize it.
Problem#
The domain being accessed is localhost/store/add_order.html, and the web root directory is /www/web. store is a subdirectory.
Solution#
Configure as follows
Default path (Mac)
/usr/local/etc/nginx/nginx.conf
server {
listen 80;
server_name localhost;
root /www/web;
#charset koi8-r;
location / {
index index.php index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ^~ /api/ {
proxy_pass http://www.api.com/;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
There are 3 matching rules in the above location:
First match location = /50x.html
Second match location ~ .php$
Finally match /
For example, http://localhost/store/add-order.html will look for the store/add-order.html file in the /www/web directory.
For example, http://localhost/store/add-order.php will combine /www/web directory and store/add-order.php into SCRIPT_FILENAME and pass it to the PHP component.
Proxy#
For example, http://localhost/api/add-order.php will be proxied to http://www.api.com/add-order.php.
But if there is no trailing /,
proxy_pass http://www.api.com;
it will be proxied to http://www.api.com/api/add-order.php.
Additional Information#
Location is used to match URLs.
It performs fuzzy matching.
Without "/", location /abc/def can match the /abc/defghi request, as well as /abc/def/ghi, etc.
With "/", location /abc/def/ cannot match the /abc/defghi request, only /abc/def/anything-like requests.
Extension#
location = / {
# Rule A
}
location = /login {
# Rule B
}
location ^~ /static/ {
# Rule C
}
location ~ \.(gif|jpg|png|js|css)$ {
# Rule D, note: matching is based on the case inside the parentheses. If all lowercase inside the parentheses, it only matches lowercase.
}
location ~* \.png$ {
# Rule E
}
location !~ \.xhtml$ {
# Rule F
}
location !~* \.xhtml$ {
# Rule G
}
location / {
# Rule H
}
The resulting effects are as follows:
Accessing the root directory /, such as http://localhost/, will match Rule A.
Accessing http://localhost/login will match Rule B, while http://localhost/register will match Rule H.
Accessing http://localhost/static/a.html will match Rule C.
Accessing http://localhost/a.gif, http://localhost/b.jpg will match Rule D and Rule E, but Rule D takes precedence and Rule E does not work. However, http://localhost/static/c.png will match Rule C first.
Accessing http://localhost/a.PNG will match Rule E and will not match Rule D because Rule E is case-insensitive.
Accessing http://localhost/a.xhtml will not match Rule F and Rule G.
Accessing http://localhost/a.XHTML will not match Rule G (because of !). Rule F and Rule G are exclusion rules, even if they match the matching rules, they will not be matched. So think about where they will be used in practical applications.
Accessing http://localhost/category/id/1111 will ultimately match Rule H because none of the above rules match. At this point, nginx forwards the request to the backend application server, such as FastCGI (php), tomcat (jsp), with nginx acting as a reverse proxy server.
Priority: (location = ) > (location full path) > (location ^~ path) > (location ~,~* regex order from top to bottom, matching in the last rule) > (location partial starting path) > (/)