webdevops nginx-从网址中删除.php要求 [英] webdevops nginx - remove .php requirement from url

查看:101
本文介绍了webdevops nginx-从网址中删除.php要求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个基于 webdevops/php-nginx:7.2 的docker,我正在尝试配置nginx以将带有或不带.php扩展名的请求路由到适当的文件./p>

如果存在 abc.php ,我需要/abc /abc.php 路由到 abc.php .其他所有内容都将转到 index.php

当前设置如下:

Dockerfile 包含

  WEB_DOCUMENT_ROOT =/app/public复制docker/opt/docker/etc/opt/docker/etc/ 

opt/docker/etc/nginx/conf.d/10-location-root.conf

 服务器{index index.html index.php;地点/{try_files $ uri $ uri//index.php?_url=$uri&$args;}} 

/app/public 包含

  index.phpabc.php 

当前,此配置将除/abc.php 之外的所有内容路由到 index.php .尝试打/abc 路由到 index.php .

谢谢:)

编辑:使用Ivan的答案,码头工人记录了垃圾邮件:

  app_1 |->执行/opt/docker/bin/service.d/nginx.d//10-init.shapp_1 |2020-10-20 10:31:59,273信息成功:nginxd进入了RUNNING状态,进程已暂停了>大于0秒(startsecs)app_1 |nginx:[emerg]未知的"_uri"多变的app_1 |2020-10-20 10:31:59,287信息退出:nginxd(退出状态1;预计不到) 

解决方案

如果我正确理解该系统的工作原理,请尝试以下两个文件作为开头:

  • /opt/docker/etc/nginx/vhost.common.d/10-location-root.conf

 位置/{try_files $ uri $ uri/@ extensionless-php;}位置@ extensionless-php {最后重写^ $ uri.php;} 

  • /opt/docker/etc/nginx/vhost.common.d/10-php.conf

 位置〜\ .php $ {try_files $ uri/< DOCUMENT_INDEX>?_ url = $ uri& $ args;fastcgi_pass php;包括fastcgi_params;fastcgi_param SCRIPT_FILENAME $ request_filename;fastcgi_read_timeout< PHP_TIMEOUT> ;;} 

以上配置有一个严重缺陷.如果请求的URI不是现有PHP文件的名称(带有或不带有 .php 扩展名),则 $ uri 内部nginx变量值将始终以 .php ,这是由于 @ extensionless-php 命名位置中的 rewrite 规则所致.这将导致以下情况(假设文件/app/public/some/path.php 不存在):

/some/path =>/index.php?_url=/some/path.php

/some/path.php =>/index.php?_url=/some/path.php

要解决此问题,我们可以将原始的 $ uri 变量值保存在名为 extensionless-php 的位置:

  • /opt/docker/etc/nginx/vhost.common.d/10-location-root.conf

 位置/{try_files $ uri $ uri/@ extensionless-php;}位置@ extensionless-php {设置$ original_uri $ uri;最后重写^ $ uri.php;} 

  • /opt/docker/etc/nginx/vhost.common.d/10-php.conf

 位置〜\ .php $ {try_files $ uri/< DOCUMENT_INDEX>?_ url = $ original_uri& $ args;fastcgi_pass php;包括fastcgi_params;fastcgi_param SCRIPT_FILENAME $ request_filename;fastcgi_read_timeout< PHP_TIMEOUT> ;;} 

此配置更好,但仍然存在缺陷.如果请求的URI以 .php 结尾,并且/app/public 目录中没有相应的PHP文件,则 $ original_uri 变量将不会将被初始化,并且 _url 查询参数将作为一个空字符串传递给后端:

/some/path =>/index.php?_url=/some/path

/some/path.php =>/index.php?_url =

这对于某些Web应用程序可能是可以的(空的 _url 查询参数始终表示无效的路由),但是如果我们想获取原始的URI,无论怎么做,该怎么办?我们可以借助 map 的帮助来实现>指令(极其强大的nginx功能).但是,所有 map 块都应在 server 块之外声明,因此我们需要一个附加文件:

  • /opt/docker/etc/nginx/conf.d/10-map.conf

  map $ _uri $ original_uri {"$ uri;默认$ _uri;} 

  • /opt/docker/etc/nginx/vhost.common.d/10-location-root.conf

 位置/{try_files $ uri $ uri/@ extensionless-php;}位置@ extensionless-php {设置$ _uri $ uri;最后重写^ $ uri.php;} 

  • /opt/docker/etc/nginx/vhost.common.d/10-php.conf

 位置〜\ .php $ {try_files $ uri/< DOCUMENT_INDEX>?_ url = $ original_uri& $ args;fastcgi_pass php;包括fastcgi_params;fastcgi_param SCRIPT_FILENAME $ request_filename;fastcgi_read_timeout< PHP_TIMEOUT> ;;} 

map 块意味着 $ original_uri 变量如果未修改,将等于 $ uri 一个($ _uri 变量未初始化且为空).如果 $ _ uri 变量不为空,则意味着原始的 $ uri 已被修改,并且 $ _ uri 变量现在保持其原始值,因此 $ original_uri 变量的值将设置为 $ _ uri .此配置应与任何将原始URI保留为 _url 查询参数的请求一起使用.

I have a docker that is based off of webdevops/php-nginx:7.2 and I am trying to configure the nginx to route requests with or without the .php extension to the appropriate file.

If abc.php exists, I need /abc and /abc.php to route to abc.php. Everything else would go to index.php

Current setup looks like:

Dockerfile contains

WEB_DOCUMENT_ROOT=/app/public
COPY docker/opt/docker/etc /opt/docker/etc/

opt/docker/etc/nginx/conf.d/10-location-root.conf

server {
  index index.html index.php;
  location / {
    try_files $uri $uri/ /index.php?_url=$uri&$args;
  }
}

/app/public contains

index.php
abc.php

Currently this configuration routes everything to index.php except for /abc.php. Trying to hit /abc routes to index.php.

Thanks :)

Edit: Using Ivan's answer the docker logs spam:

app_1  | -> Executing /opt/docker/bin/service.d/nginx.d//10-init.sh
app_1  | 2020-10-20 10:31:59,273 INFO success: nginxd entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
app_1  | nginx: [emerg] unknown "_uri" variable
app_1  | 2020-10-20 10:31:59,287 INFO exited: nginxd (exit status 1; not expected)

解决方案

If I correctly understand how this system works, lets try the two following files for the beginning:

  • /opt/docker/etc/nginx/vhost.common.d/10-location-root.conf

location / {
    try_files $uri $uri/ @extensionless-php;
}
location @extensionless-php {
    rewrite ^ $uri.php last;
}

  • /opt/docker/etc/nginx/vhost.common.d/10-php.conf

location ~ \.php$ {
    try_files $uri /<DOCUMENT_INDEX>?_url=$uri&$args;
    fastcgi_pass php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_read_timeout <PHP_TIMEOUT>;
}

The above configuration has one serious flaw. If the requested URI isn't the name of an existing PHP file (with or without the .php extension), a $uri internal nginx variable value will always end with .php due to the rewrite rule inside of the @extensionless-php named location. This would lead to the following (assuming file /app/public/some/path.php doesn't exist):

/some/path => /index.php?_url=/some/path.php

/some/path.php => /index.php?_url=/some/path.php

To fix this issue we can save the original $uri variable value inside the extensionless-php named location:

  • /opt/docker/etc/nginx/vhost.common.d/10-location-root.conf

location / {
    try_files $uri $uri/ @extensionless-php;
}
location @extensionless-php {
    set $original_uri $uri;
    rewrite ^ $uri.php last;
}

  • /opt/docker/etc/nginx/vhost.common.d/10-php.conf

location ~ \.php$ {
    try_files $uri /<DOCUMENT_INDEX>?_url=$original_uri&$args;
    fastcgi_pass php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_read_timeout <PHP_TIMEOUT>;
}

This configuration is better, but still has a flaw. If the requested URI ends with .php and there is no corresponding PHP file in the /app/public directory, the $original_uri variable won't be initialized and the _url query argument would be passed to backend as an empty string:

/some/path => /index.php?_url=/some/path

/some/path.php => /index.php?_url=

This could be ok for some web applications (empty _url query argument always meaning an invalid route), but what do we have to do if we want to get an original URI whatever it is? We can achieve it with the help of the map directive (an extremely powerful nginx feature). However all map blocks should be declared outside the server blocks, so we would need an additional file:

  • /opt/docker/etc/nginx/conf.d/10-map.conf

map $_uri $original_uri {
    ""          $uri;
    default     $_uri;
}

  • /opt/docker/etc/nginx/vhost.common.d/10-location-root.conf

location / {
    try_files $uri $uri/ @extensionless-php;
}
location @extensionless-php {
    set $_uri $uri;
    rewrite ^ $uri.php last;
}

  • /opt/docker/etc/nginx/vhost.common.d/10-php.conf

location ~ \.php$ {
    try_files $uri /<DOCUMENT_INDEX>?_url=$original_uri&$args;
    fastcgi_pass php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $request_filename;
    fastcgi_read_timeout <PHP_TIMEOUT>;
}

This map block means that the $original_uri variable would be equal to $uri one if it wasn't modified ($_uri variable isn't initialized and empty). If the $_uri variable is not empty it means that the original $uri was modified and the $_uri variable now keeps its original value, so the value of the $original_uri variable would be set to $_uri. This configuration should work with any requests preserving original URI as _url query argument.

这篇关于webdevops nginx-从网址中删除.php要求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆