Nginx在动态之前提供静态页面


Nginx to serve static page before dynamic

我想用NGINX提供静态HTML文件,但如果文件丢失,它应该加载一个PHP文件,PHP应该处理内容。

我一直在测试几种try_files组合,但我无法理解它。我有一个虚拟的PHP应用程序,看起来像这样:

./
../
dynamic.php
index.php
static/
static/static.html

然后我在索引上有一个小的PHP代码,如下所示:

<?php
$path = $_SERVER['REQUEST_URI'];
$pattern = '/^'/(.*)'.html$/';
$matches = [];
$results = preg_match($pattern, $path, $matches);
if (count($matches) > 0) {
    if ($matches[1] == "dynamic") {
        require 'dynamic.php';
    } else {
        echo "Not found!";
    }
} else {
    echo "Index page!";
}

浏览到每个页面的结果应为:

http://foo.bar/             - Loads index.php
http://foo.bar/static.html  - Loads static/static.html
http://foo.bar/dynamic.html - Loads index.php & PHP requires dynamic.php
http://foo.bar/baz.html     - Loads index.php with "not found" message

这是我在NGINX配置文件中得到的:

server {
    listen 80;
    server_name .foo.bar *.foo.bar;
    access_log /var/log/nginx/foo.access.log;
    error_log  /var/log/nginx/foo.error.log;
    root /var/www/foo;
    index index.php;
    location / {
        # Trying with 'try_files' here. No success.
    }
    location ~ '.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+'.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

我一直在反复尝试,显然完全失败了:

try_files $uri $uri/static /index.php;

我错过了一些东西。帮助?

我会使用您的静态目录作为文档根目录。这可确保没有人可以直接执行/dynamic.php,但是,它将通过命名的位置块@php转发到您的index.php

此配置示例未经测试!

server {
    index       index.php;
    root        /var/www/foo/static;
    server_name foo.bar *.foo.bar;
    location / {
        try_files $uri @php;
    }
    location @php {
        include fastcgi_params;
        fastcgi_pass  unix:/var/run/php5-fpm-foo.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/foo/index.php;
    }
}
  1. 如果 listen 指令仅包含 80,则不需要它,因为这是默认值。
  2. server_name不应包含前导点。
  3. $uri始终包含请求的 URI,包括前导斜杠(例如 /static.html ),nginx 将在调用try_files时用文档根作为前缀(例如 /var/www/foo/static.html )。因此,您需要在$uri之前设置static目录(例如 /static$uri变成/var/www/foo/static/static.html)。
  4. 您不需要fastcgi_split_path_info因为您没有使用该功能。
  5. 您在PHP位置中的try_files使nginx无法正确转发内容。/dynamic.html请求不会在.php结束,因此,try_files总是失败。
有多种

方法可以从 URL 中隐藏static目录。例如,操纵root,巧妙地使用try_filesrewrite

可能最明显的是:

root /var/www/foo;
location / {
    root /var/www/foo/static;
    try_files $uri /index.php;
}
location ~ '.php$ { ... }

这样nginxstatic文件夹中查找普通文件,但在父文件夹中查找.php文件。

您试图实现的是这样的:

root /var/www/foo;
location / {
    try_files /static$uri /index.php;
}
location ~ '.php$ { ... }

它将在测试是否存在之前将/static前缀添加到任何 URI。/index.php必须是最后一个元素,因为它需要在不同的位置进行处理。有关详细信息,请参阅此文档。

根据您给出的具体示例案例,下面的配置将返回您列出的结果。

server {
    listen 80;
    server_name .foo.bar *.foo.bar;
    access_log /var/log/nginx/foo.access.log;
    error_log  /var/log/nginx/foo.error.log;
    root /var/www/foo;
    index index.php;
    location ~ '.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+'.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    location ~ /static {
        rewrite ^/static'.html$ /static/ last;
        index static.html;
    }
    location ~ / {
        rewrite ^ /index.php last;
    }

那是。。。

http://foo.bar/             - Loads index.php
http://foo.bar/static.html  - Loads static/static.html
http://foo.bar/dynamic.html - Loads index.php & PHP requires dynamic.php
http://foo.bar/baz.html     - Loads index.php with "not found" message