Nginx Location配置 – 被坑记

server {
    listen       80;
    server_name  xxx.com;
    root /mnt/xxx/public;
    index index.php;

    error_page 404 /index.php;
    
    if (!-e $request_filename) {
        rewrite ^/(.+)$ /index.php last;
        break;
    }

    location / {
	root /var/xxx/public;
        #尝试实际文件,然后判断是不是目录,在然后就是到首页(实际是被重新,重新发起location匹配)
	try_files $uri $uri/ /index.php?$query_string; 
    }

    location ~* ^.+\.(css|js|jpeg|jpg|gif|png|ico|eot|ttf|woff|svg) {
        expires 30d;
    }

    location ~* \.(eot|ttf|woff|svg|html)$ {
        add_header Access-Control-Allow-Origin *;
    }

    location ~ \.php$ {
	client_max_body_size 500M;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
        fastcgi_buffer_size 32k;
        fastcgi_buffers 256 32k;

        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
        #fastcgi_param APPLICATION_ENV testing;
   }

首先,第一个if语句是判断对应的rui不存在(非目录和文件),那么就重写到index.php,我们知道last重写相当于continue语句,由于这个if在server块中,所以它不会再次发起请求了,故而下面的break是多余的,写上也没有问题。

还是再次复习location指令的用法吧:
location指令
语法:location [=|~|~*|^~] /uri {…} 注意看明白格式****中括号表示可以省略
使用环境:server

该指令运行对不同的URI进行不同的配置,即可以使用字符串,也可以使用正则表达式。使用正则表达式,须使用以下前缀。
1 ~* 表示不区分大小写的匹配
2 ~ 表示区分大小写的匹配
(意思是以这两个字符开头的,就是一定是正则匹配)
在匹配过程中,Nginx将首先匹配字符串,然后再匹配正则表达式。匹配到第一个正则表达式后,会停止搜索(搜索顺序时先出现的优先)。如果匹配到正则表达式,则使用正则表达式匹配,如果没有匹配到正则表达式,则使用字符串的搜索结果。

特殊用法:
可以使用前缀^~来禁止匹配到字符串后,再去检查正则表达式。
使用前缀=可以进行精确的URI匹配,如果找到匹配的URI,则停止查询。

注意,Nginx中的变量$uri由于都是以/开头的,当访问首页是其实访问的就是/,浏览器总是把斜杠添加上然后才发出请求,就算没有加上斜杠发出来了请求,服务器也会进行一个加了斜杠的重定向,如果访问一个目录时,请求到达服务器后如何确认它是一个目录,服务器会进行一个加了斜杠的重定向。

另外,location指令中能使用的前缀只有上面列出的四个,而那些在if中合法的!~ 和 !~*在location中是不合法的,这个稍不注意就会让人困惑。

location的正则匹配是一旦匹配就停止,所以那些允许的匹配应该写在前,不允许的应该写在后,具体的写在最前面。

所有的location匹配放入一个循环,字符串优先匹配(最先的先匹配,后面的后匹配),然后匹配正则,正则一旦匹配,就使用这个正则匹配(触发被重写,会重新发起一次对locaiton的匹配),否则就使用最后的字符匹配,总体上满足先具体,后一般的原则。

回到配置,第一个字符匹配,基本上,如果后面的没有匹配,就都是它了。后面的是三个正则匹配,一旦匹配,就用它。现在假如URI是get.js.php 和 get.css.php,这个时候它匹配了第二个正则而不是第三个正则,所以被坑就在这里了。导致明明要执行PHP脚本的,生硬的把get.js.php源码返回。争取的写法应该是在最后加上$字符。