在我的URL重写规则中获取500内部服务器错误

时间:2013-12-05 00:45:21

标签: regex .htaccess mod-rewrite url-rewriting rewrite

如果有以下可能的网址:

http://stackoverflow.com/categories/
http://stackoverflow.com/categories/category-type
http://stackoverflow.com/categories/category-type/category
http://stackoverflow.com/categories/category-type/category/sub-category

我要重写为

http://stackoverflow.com/categories/
http://stackoverflow.com/categories/?category-type=category-type
http://stackoverflow.com/categories/?category-type=category-type&category=category
http://stackoverflow.com/categories/?category-type=category-type&category=category&sub-category=sub-category

这是我的重写规则:

RewriteRule ^categories/([^/]*)/([^/]*)/([^/]+)(/)?$ /categories/?category-type=$1&category=$2&sub-category=$3 [NC,L]

RewriteRule ^categories/([^/]*)/([^/]+)(/)?$ /categories/?category-category=$1&category-=$2 [NC,L]

RewriteRule ^categories/([^?][^/]*)(/)?$ /categories/?category-type=$1 [NC,L]

最后一条规则导致500 Internal Server Error。造成这种情况的原因是什么?

6 个答案:

答案 0 :(得分:4)

  

最后一条规则导致500内部服务器错误。造成这种情况的原因是什么?

这是一个循环。您的规则的目标/categories/与模式^categories/([^?][^/]*)(/)?$匹配,因为/之后的所有内容都是可选的。尝试使*成为+以强制至少1个字符:

RewriteRule ^categories/([^?][^/]+)(/)?$ /categories/?category-type=$1 [NC,L]

答案 1 :(得分:1)

最后规则中的正则表达式似乎有问题。请在DOCUMENT_ROOT/.htaccess文件中试用这些规则:

RewriteEngine On

RewriteRule ^categories/([^/]+)/([^/]+)/([^/]+)/?$ /categories/?category-type=$1&category=$2&sub-category=$3 [NC,QSA,L]

RewriteRule ^categories/([^/]+)/([^/]+)/?$ /categories/?category-type=$1&category=$2 [NC,QSA,L]

RewriteRule ^categories/([^/]+)/?$ /categories/?category-type=$1 [NC,QSA,L]

答案 2 :(得分:1)

我们可以在这里永远地试图修复它,但是一旦你创建了一些新的url类型,你就会再次变得愚蠢。我曾经在我的旧网站中使用复杂的httacess,但是几年前,我没有在httacces中添加太多逻辑,这是一个php路由器的代理。

这是一个更灵活的解决方案,您可以创建更复杂的规则,更改所有内容更容易,并且如果您更改服务器,在其他服务器或其他文件夹中安装应用程序或添加新路由,也可以完美运行。

这是Zend Framework 2的主要内容,或多或少与我使用的相似:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

所有规则意味着如果请求不是实际文件或目录,只需将其发送到index.php

在索引php中,你解析实际的url并填充你的$ _GET变量。

答案 3 :(得分:1)

你的最后一次重写落入一个无法解决的循环中!你需要的是改变你的规则以避免这种情况,比如提出一个条件:

RewriteRule ^categories/([^/]*)/([^/]*)/([^/]+)(/)?$ /categories/?category-type=$1&category=$2&sub-category=$3 [NC,L]
RewriteRule ^categories/([^/]*)/([^/]+)(/)?$ /categories/?category-type=$1&category-=$2 [NC,L]
RewriteCond %{QUERY_STRING}  !category-type
RewriteRule ^categories/([^\/]+)/?$ /categories/?category-type=$1 [NC,L]

这样,如果查询字符串中有category-type,它就不会重写URL。

答案 4 :(得分:1)

我不确定我的方法是否会有所帮助,因为我的原始.htaccess规则在我测试时实际上对我有效,这可能表明它可能是一个配置问题。为清楚起见,您发布的此代码为我工作:

RewriteRule ^categories/([^/]*)/([^/]*)/([^/]+)(/)?$ /categories/?category-type=$1&category=$2&sub-category=$3 [NC,L]

RewriteRule ^categories/([^/]*)/([^/]+)(/)?$ /categories/?category-category=$1&category-=$2 [NC,L]

RewriteRule ^categories/([^?][^/]*)(/)?$ /categories/?category-type=$1 [NC,L]

这没有任何修改(除了设置“RewriteEngine On”)。我建议发布相关的Apache配置,或者至少最低限度地发布你正在使用的Apache版本,Apache日志文件的摘录以及整个.htaccess。

以下是我个人建议的内容,根据需要删除“R = 301”(我只是用它来实际查看地址更改):

RewriteEngine On
RewriteBase /


# Is the request is for a file, directory, or symlink?

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]

# If the request is for a file, directory, or symlink then skip the next 3 rules.
RewriteRule .? - [S=3,L]

RewriteRule ^categories/([^/]*)/([^/]*)/([^/]*)(/)?$ /categories/?category-type=$1&category=$2&sub-category=$3 [NC,R=301,L]
RewriteRule ^categories/([^/]*)/([^/]*)(/)?$ /categories/?category-type=$1&category=$2 [NC,R=301,L]
RewriteRule ^categories/([^?][^/]*)(/)?$ /categories/?category-type=$1 [NC,R=301,L]

如果这不起作用,您是否尝试使用“END”而不是“L”标志作为规则?

RewriteRule ^categories/([^/]*)/([^/]*)/([^/]*)(/)?$ /categories/?category-type=$1&category=$2&sub-category=$3 [NC,R=301,END]
RewriteRule ^categories/([^/]*)/([^/]*)(/)?$ /categories/?category-type=$1&category=$2 [NC,R=301,END]
RewriteRule ^categories/([^?][^/]*)(/)?$ /categories/?category-type=$1 [NC,R=301,END]

禁用“FollowSymlinks”会做什么吗?

Options –FollowSymlinks

除了所有这些之外,如果您回答了许多其他可能的答案,将会很有帮助。弗洛里斯指出我在第二条规则中看到的一个错误; “category-category”,而不是“category-type”。除此之外,在同一部分规则的末尾可能存在错误,因为我假设您打算“category = $ 2”而不是“category - = $ 2”。 (我在我的建议中做了两个修正)

Anubhava准确地提到错误日志非常有用。

多人隐式修改(Anubhava)或明确建议(Jon Lin)你应该强制每个URI部分中至少有一个字符。我没有自己修改的唯一原因是因为它对我来说是开箱即用的,我只是假设你设计它时你有合理的理由使用“*”而不是“+”(尽管有回应致Jon Lin);表示在你的表达式中使用不一致,有时你使用“+”,有时你在我预期的一致性使用“*”。我在我的建议中修改了任何“+”到“*”以保持一致性,即使我个人同意它们对于所有人来说更有意义的是始终是“+”。

卡洛斯也提出了一个好点;你是否正在使用它作为抽象,你应该重新思考你的规则应该如何设计?

  

参考文献:

     

http://httpd.apache.org/docs/current/rewrite/flags.html   http://httpd.apache.org/docs/2.2/mod/core.html#options

答案 5 :(得分:0)

你的第二条规则中显然存在拼写错误:

RewriteRule ^categories/([^/]*)/([^/]+)(/)?$ /categories/?category-category=$1&category-=$2 [NC,L]

应该是

RewriteRule ^categories/([^/]*)/([^/]+)(/)?$ /categories/?category-type=$1&category-=$2 [NC,L]
                                                    error is here  ^^^^

我想知道你是否最终得到了格式错误的请求 - 换句话说,并不是你的表达式错误,而是服务器不接受你的结果请求。如果您关闭重写并直接在浏览器中输入实际请求会发生什么?