ChatGPT解决这个技术问题 Extra ChatGPT

如何使用 NGINX 直接提供所有现有的静态文件,但将其余的代理到后端服务器。

location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    if (-f $request_filename) {
        access_log off;
        expires 30d;
        break;
        }

    if (!-f $request_filename) {
        proxy_pass http://127.0.0.1:8080; # backend server listening
        break;
        }
    }

以上将直接使用 Nginx 提供所有现有文件(例如 Nginx 仅显示 PHP 源代码),否则将请求转发给 Apache。我需要从规则中排除 *.php 文件,以便对 *.php 的请求也传递给 Apache 并进行处理。

我希望 Nginx 处理所有静态文件,而 Apache 处理所有动态文件。

编辑:有白名单方法,但不是很优雅,查看所有这些扩展,我不想要这个。

location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
    access_log off;
    expires 30d;
    }
location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
    }

编辑 2:在较新版本的 Nginx 上使用 try_files 而不是 http://wiki.nginx.org/HttpCoreModule#try_files

只是为了澄清一下:如果磁盘上存在静态文件,上面的代码将提供一个静态文件,如果该文件不存在,则将请求传递给 Apache。这在大多数情况下都有效,因为我的应用程序中的所有 URL 都使用 mod_rewrite(或路由)并且实际上并不存在于磁盘上。只有直接访问 *.php 文件名是例外,需要 Apache 解析。

C
Chuan Ma

使用 try_files 和命名的位置块 ('@apachesite')。这将删除不必要的正则表达式匹配和 if 块。更高效。

location / {
    root /path/to/root/of/static/files;
    try_files $uri $uri/ @apachesite;

    expires max;
    access_log off;
}

location @apachesite {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

更新: 此配置的假设是 /path/to/root/of/static/files 下不存在任何 php 脚本。这在大多数现代 php 框架中很常见。如果您的旧 php 项目在同一文件夹中混合了 php 脚本和静态文件,您可能必须将您希望 nginx 服务的所有文件类型列入白名单。


我正在使用 wordpress,所以我需要将上传文件夹放在 nginx 服务器上吗?
我对这个解决方案的问题:nginx 不使用其他位置(代理)并尝试显示目录列表。因此它会抛出 403,因为目录列表未激活。 编辑: 好的,如果您删除 $uri/,那么它可以工作。
这会将 /example 代理到 apache,但允许下载 /example.php。
@TerenceJohnson 将 php 文件放在静态文件夹下是不安全的。请注意,我设置了 root /path/to/root/of/*static*/files;。 php 文件应放在不同的文件夹中,不能直接从 Internet 访问。
我知道事情应该是这样的,但是如果有人将 Nginx 放在许多常见的现成 PHP 应用程序的前面,这些应用程序的所有内容都在 web 根目录下并依赖 .htaccess 文件,那么他们不应该复制和粘贴您的配置。
J
Jasiu

尝试这个:

location / {
    root /path/to/root;
    expires 30d;
    access_log off;
}

location ~* ^.*\.php$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

希望它有效。正则表达式比纯字符串具有更高的优先级,因此如果仅存在相应的 .php 文件,则所有以 .php 结尾的请求都应转发到 Apache。休息将作为静态文件处理。评估位置的实际算法是here


l
lo_fye

如果您使用 mod_rewrite 来隐藏脚本的扩展名,或者您只是喜欢以 / 结尾的漂亮 URL,那么您可能想从另一个方向处理这个问题。告诉 nginx 让任何带有非静态扩展的东西通过 apache。例如:

location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$
{
    root   /path/to/static-content;
}

location ~* ^!.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$ {
    if (!-f $request_filename) {
        return 404;
    }
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://127.0.0.1:8080;
}

我在以下位置找到了此代码段的第一部分:http://code.google.com/p/scalr/wiki/NginxStatic


这很好用,尽管我仍然收到缩小文件的错误(例如 site.min.css 和 main.min.js 等)。我将如何在位置正则表达式中捕获那些? @lo_fye

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅