4

我有一个基本的 MVC 系统,它将 POST 数据发送到 URL,例如

管理员/产品/添加/

但这给了我一个错误

禁止的

您无权访问此服务器上的 /admin/product/add/。

此外,在尝试使用 ErrorDocument 处理请求时遇到 404 Not Found 错误。

RewriteRule 很简单

RewriteRule ^(.*)/$ index.php?uri=$1

上次我在服务器上看到这个将文件/目录权限更改为 755 似乎解决了它,但这次没有。我从来没有真正理解错误的原因,所以希望有人能够提供更多信息?

4

3 回答 3

9

您有 2 个错误:

  1. 您无权访问此服务器上的 /admin/product/add/。
  2. 此外,在尝试使用 ErrorDocument 处理请求时遇到 404 Not Found 错误。

第二个肯定是同一个错误的结果。您的 apache 配置中可能有一些东西可以从默认的 http 服务器处理中删除 404 错误并将其推送到您的 php 应用程序,如果这个 php 应用程序正在运行,我们将有一个不错的 404,但是......

第一个告诉您您的 php 应用程序根本没有运行。

所以。第一个错误告诉我们 apache 确实尝试直接访问/path/to/documentroot/admin/product/add/您服务器上的目录并生成它的列表(只有当 apache 被授权这样做时才会列出目录内容)。但是,这当然不是您服务器上的真实目录。它是应用程序中的虚拟路径。所以 apache 以 404 结束(导致错误 2)。

应用程序处理虚拟路径,apache 不管理它。RewriteRule 的工作是在apache 尝试提供请求之前捕获请求的路径,并将其index.php作为查询字符串参数提供给单个 php 文件 ()。

所以......这个重写规则没有应用。可能阻止应用此规则的事情有很多:

  1. mod_rewrite 未激活:模块是否存在并启用(RewriteEngine on)?
  2. 语法错误:mod rewrite 语法很难阅读,有时真的很复杂。但在这里看起来很简单。
  3. RewriteRule 结果文件可能不是 apache 的有效目标。如果 index.php 文件不在 DocumentRoot 中,或者 apache 用户无法读取,则 apache 将失败。警告:拥有 apache 用户可读的文件意味着对文件具有读取权限,而且对 apache 用户的所有 父目录具有执行权限。这是您的经典/解决方案正在解决问题的地方。chmodchown
  4. 该规则必须位于有效的配置文件中。此规则是否在位置或目录部分内的 apache 配置文件中?或者可能在全局范围内——这可能会改变重写规则语法——。还是在 .htaccess 文件中?如果它是 .htacces,apache 是否会读取 .htacces 文件,并且那里允许使用 mod-rewrite 指令(AllowOverride None)。没有其他 .htaccess 文件优先吗?

所以要解决这个问题:

  • 如果您的 apache 版本高于 2.2.16,您可以将 RewriteRule 替换为FallbackRessource /index.php以检查这不是来自 mod-rewrite 问题。
  • 尝试直接请求index.php,以便至少对该文件的直接请求有效
  • 尝试直接访问 documentRoot 上的有效资源(txt 文件、图像、不应该由重写处理但直接提供的东西)
  • 检查您的任何虚拟路径是否可以映射真实的物理路径 Apache 并未尝试为物理路径提供服务(例如当您编写 a 时RewriteCond %{REQUEST_FILENAME}-d),而是将路径真正推送到index.php
  • 检查 apache 错误日志
  • RewriteLog使用and调试mod_rewriteRewriteLogLevel
  • 收集事实、设置和测试,然后将其推送到 SO 或Servfault

所以问题很简单:php 应用程序没有收到请求。但是有很多方法可以结束这种状态。消息本身并不是很重要。找到错误的唯一方法是检查所有参数(或者拥有多年的错误修复经验并为灯错误开发预认知直觉器官 - 通常是胡须 - 就像管理员一样)。我们帮助您的唯一方法是在大量配置细节中找到奇怪的事实,这就是为什么好的问题包含大量信息,即使所有这些信息对您来说看起来都只是“经典”。

编辑

要澄清问题,您应该编辑您的答案,POST 使用 Chrome 开发者工具或 firebug 等工具跟踪请求(将网络跟踪保持在记录模式以捕获多个 POST)或尝试使用 Live HTTP 标头回复重播该帖子。您应该尝试隔离有问题的 POST 并向我们提供详细信息。调试并不神奇。

现在我知道一个神奇的随机 POST 失败。这是空的GET url 错误。可能是(或不是)。例如,如果您在某处隐藏了一个空的 GET url ( <IMG SRC="">url()在 css 中,或者在标头中有一个空的 LINK。因为这些隐藏的 POST 在 HTTP 中定义为“replay-the-request-which-launched-the-source-page,并且一些浏览器甚至会重放 POST,如果他们找到了就会给你的页面。这可能会导致隐藏的 POST 被破坏。

也可能是 POST 未发送到正确的服务器。很难说。因此,请从您的评论中收集信息,添加更多网络分析并编辑现在确实包含的事实不足的问题。

于 2013-01-20T22:45:05.283 回答
1

尝试这个:

RewriteCond %{REQUEST_METHOD} =POST
RewriteRule ^(.*)/$ index.php?uri=$1
于 2012-12-10T20:54:01.817 回答
1

用这个:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?uri=$1 [L]

也只能使用 www 或非 www 域,但不能同时使用两者。使用 htaccess 将用户重定向到您想要的位置...

非万维网到万维网:

RewriteCond %{HTTP_HOST} !^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

万维网到非万维网:

RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^www\.(.*)$ http://%1/$1 [R=301,L]
于 2013-01-24T23:36:50.600 回答