Nginx重写规则导致错误403

Nginx重写规则导致错误403,nginx,url-rewriting,http-status-code-403,Nginx,Url Rewriting,Http Status Code 403,我正在尝试重写一个类似http://example.com/extras/?cat=help&page=faq类似于http://example.com/extras/help/faq 好吧,在一个链接中重写,或者用户键入后者,服务器就会明白它应该是前者。然而,在实现了表面上应该做我想做的事情的重写之后,导航到页面会产生403代码,因为服务器从字面上理解了URL栏中的内容。由于我已将服务器设置为不允许直接访问子文件夹,因此返回403代码 下面是我网站上的php代码,用于加载要包含在/extras

我正在尝试重写一个类似
http://example.com/extras/?cat=help&page=faq
类似于
http://example.com/extras/help/faq

好吧,在一个链接中重写,或者用户键入后者,服务器就会明白它应该是前者。然而,在实现了表面上应该做我想做的事情的重写之后,导航到页面会产生403代码,因为服务器从字面上理解了URL栏中的内容。由于我已将服务器设置为不允许直接访问子文件夹,因此返回403代码

下面是我网站上的php代码,用于加载要包含在
/extras
index.php中的页面:

if(!empty($_GET['cat']) && !empty($_GET['page'])) {
  $folder = $_GET['cat'];
  $page = $_GET['page'] . '.php';
  $pages = scandir($folder);
  unset($pages[0], $pages[1]);

  $url .= $folder . DIRECTORY_SEPARATOR;

  if(file_exists($url . $page) && in_array($page, $pages)) {
    $url .= $page;
    include($url);
  } else {
    //Invalid category or page given
    header("HTTP/1.0 404 Not Found");
  }
} else {
  //No category or page given; fall back to contents
  include("contents.php");
}
上述文件的目标是将子文件夹中的子文件内容包含在index.php的正文中,而不是让浏览器实际尝试并导航到该子文件

这是nginx配置的一部分:

server {
  listen 80 default_server;
  listen [::]:80 ipv6only=on;

  root /usr/share/nginx/html;

  server_name localhost;

  error_page 403 /;
  error_page 404 /error/404.php;
  error_page 500 502 503 504 /error/50X.php;

  index index.html index.htm index.php;

  location / {
    try_files $uri $uri/ @no-extension;

    allow 192.168.0.0/24;
    allow 127.0.0.1;
    deny all;
  }

  location /help {
    try_files $uri $uri/ @help @no-extension;
  }

  location @help {
    rewrite "^/help/([^/]*)/([^/]*)$" /help/?cat=$1&page=$2 last;
  }

  location ~ /help/(help|otherfolder|morefolders) {
    deny all;
  }

  # PHP Handler
  location ~ \.php$ {
    try_files $uri $uri/ =404;

    include fastcgi_params;
    fastcgi_pass php5-fpm-sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param QUERY_STRING $query_string;
    fastcgi_intercept_errors on;
  }

  location @no-extension {
    rewrite ^(.*)$ $1.php last;
  }
}

有没有办法让重写生效,而不是让浏览器尝试访问它永远无法访问的文件?

虽然没有准确回答您的问题,但这样做会不会更简单

location /help {
    try_files $uri $uri/ /index.php;

当您将/help/faq/its传入的REQUEST_URI加载到/index.php时,后续的正则表达式拆分和文件包括…无需重写。要限制的特定位置块应该放在上面,因此拒绝将首先匹配(如果我没有记错的话)

指令
try\u files$uri$uri/@help@no extension应该做什么?我更习惯于Apache重写,但我知道这可能是个问题。但是,我无法删除$uri$uri/part,或者网站中断,因为它拒绝将index.php加载到“help”文件夹中。这正是其他位置块“有效”的地方,我也希望它在这里也能起作用。我急切地等待关于我哪里出错的指示。(我不是在挖苦人,我的意思是。)如果URL是包含PHP参数的标准URL,那么该网站就可以完美运行。我想要完成的是改变URL在浏览器栏中的外观,以及允许链接正常工作,因为我认为URL中的参数有点难看。也许我在你的解释中遗漏了什么?它对以/help开头的每个url都是execute/index.php。因此/help/file/faq或/help/otherfile/sub将在/root中运行index.php,并且该php脚本可以找到您通过http头请求输入的url,这将为您提供上面的字符串“/help/file/faq”或其他内容。仍然在php中,请拆分/file/和/faq/并继续当前的脚本。用户仍然会看到example.com/folder/page,即使是内部运行的example.com/index.php。想说得更清楚点,好点吗?是的,我想我完全知道你在说什么。我会在可能的时候尝试一下,然后把这个标记为回答。