【问题标题】:Nginx to serve static page before dynamicNginx 在动态之前提供静态页面
【发布时间】:2016-05-30 00:42:36
【问题描述】:

我想用 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;

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

【问题讨论】:

  • 在您的情况下是否可以进行一些 URL 重写但一直使用 PHP 处理显示的页面?

标签: php nginx


【解决方案1】:

我会使用您的静态目录作为文档根目录。这确保没有人可以直接执行/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_names 不应包含前导点。
  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 总是失败。

【讨论】:

  • .example.comexample.com *.example.com;两者结合使用没有意义。
  • 实际上您不能在@php 位置内添加try_files,因为那里不存在dynamic.html 文件并且nginx 不会将请求转发到php-fpm。但是,我更改了配置以解决您提到的问题。
  • 对不起,我误解了你的观点 2。我以为你是说永远不应该使用带前导点的服务器名称。我完全同意你的分析
  • 是的,忘记我提到它了 :-)
【解决方案2】:

有多种方法可以从 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 必须是最后一个元素,因为它需要在不同的位置进行处理。请参阅this document 了解更多信息。

【讨论】:

  • 感谢您指出我犯的错误,但您的建议也不起作用。当尝试转到/ 时,我被重定向到//static/(带有两个正斜杠),当我尝试转到/static.html 时,我被重定向到/static/。 =/
  • @Apollo 我无法重现您的故障模式,但我确实需要在第一个示例中添加 try_files 语句。
  • @Apollo,您使用此答案中的两个示例中的哪一个来获得评论中描述的失败?
  • @Richard,使用第一个示例,foo.bar/ 确实有效,但 URI 更改为 foo.bar//static/foo.bar/static.html 重定向到 index 并将 URI 更改为 foo.bar/static/foo.bar/dynamic.html 工作; foo.bar/baz.html 产生一个空白页。
  • @Richard,使用第二个例子,结果是一样的。谢谢!
【解决方案3】:

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

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

【讨论】:

    猜你喜欢
    • 2019-07-01
    • 1970-01-01
    • 2023-03-13
    • 2019-02-12
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    相关资源
    最近更新 更多