apache - htaccess RewriteRule:在第一个参数之后省略所有的问题
问题描述
目标:想要重写所有类型的 URL
https://www.example.com/page/1234/?/blog/foo/bar/
至
https://www.example.com/page/1234/
在.htaccess
我尝试了很多变化
RewriteEngine On
RewriteBase /
RewriteRule ^page/(\d+)/(.*)$ /page/$1 [R=301,L]
使用.htaccess
测试仪,我发现至少匹配模式是有效的。
我希望重写后不会包含任何内容$1
,但它确实包含,并显示完整的原始 URL。
我错过了什么?
解决方案
https://www.mypage.com/page/1234/?/blog/foo/bar/
第一个之后的所有内容都是 URL?
的查询字符串部分。默认情况下,Apache 将请求中的查询字符串原封不动地传递给目标 URL(除非您自己在RewriteRule
替换上创建新的查询字符串)。这解释了为什么您在目标 URL 上看到相同的查询字符串,而似乎没有对其进行任何操作。
顺便说一句,该RewriteRule
模式仅与 URL 路径匹配——这特别排除了查询字符串。要匹配 mod_rewrite 中的查询字符串,您需要一个额外的条件来检查QUERY_STRING
服务器变量。
在 Apache 2.4+ 上,您可以使用QSD
(Query String Discard) 标志从目标 URL 中删除查询字符串。或者,在替换上指定一个空查询字符串- 通过包含尾随?
(其?
本身不会出现在结果 URL 上)。
例如(在 Apache 2.4 上):
RewriteCond %{QUERY_STRING} .
RewriteRule ^page/(\d+)/ /page/$1/ [QSD,R=301,L]
该RewriteCond
指令检查是否存在查询字符串,这是防止重定向循环所必需的。
图案(.*)$
上的尾随是多余的。RewriteRule
您省略了替换末尾的斜杠(位于示例 URL 中)。这也可以防止重定向循环,但如前所述,这与您的示例不同。(或者,您可以在捕获的反向引用中包含斜线。)
如果您仍在使用 Apache 2.2,那么您需要包含尾随?
而不是QSD
标志。例如:
RewriteRule ^page/(\d+)/ /page/$1/? [R=301,L]
您需要在测试前清除浏览器缓存,因为 301(永久)重定向会被浏览器永久缓存。出于这个原因,首先使用 302(临时)重定向进行测试通常更容易。
推荐阅读
- java - 如何在二维数组java中获得最小值
- google-ads-api - google adwords(googleads)的python api在调用OfflineConversionAdjustmentFeed操作时给出“INVALID_CONVERSION_TYPE”
- java - 使用 WebServiceTemplate 和 SOAP 发送 HTTP GET 请求
- ios - Swift closure is still in memory after VC deinit is called
- c++ - 添加 QWidget 时 QStackedWidget 内存泄漏
- loopbackjs - 在 loopback4 中使用 hasMany 关系和级联 ORM 级别
- python - 使用 shift() 和 groupby() 使用每组移动时间序列数据会导致 NaN
- apache-flink - 为什么 flink 中的有状态源需要同步锁
- laravel - Laravel 5.8 @csrf 和 @method 不起作用
- rust - 将不可变结构传递给多个闭包