如何使用 NGINX 直接提供所有现有的静态文件,但将其余的代理到后端服务器。
Posted
技术标签:
【中文标题】如何使用 NGINX 直接提供所有现有的静态文件,但将其余的代理到后端服务器。【英文标题】:How to serve all existing static files directly with NGINX, but proxy the rest to a backend server. 【发布时间】:2010-10-26 12:31:53 【问题描述】: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;
Above 将直接使用 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解析。 【参考方案1】:使用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文件,他们不应该复制和粘贴您的配置。【参考方案2】:
如果您使用 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;
我在以下位置找到了这个 sn-p 的第一部分:http://code.google.com/p/scalr/wiki/NginxStatic
【讨论】:
这很好用,虽然我仍然收到缩小文件的错误(例如 site.min.css 和 main.min.js 等)。我将如何在位置正则表达式中捕获那些? @lo_fye【参考方案3】:试试这个:
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。
【讨论】:
以上是关于如何使用 NGINX 直接提供所有现有的静态文件,但将其余的代理到后端服务器。的主要内容,如果未能解决你的问题,请参考以下文章
如何将 CORS(跨域策略)添加到 NGINX 中的所有域?