微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用mod_rewrite和Apache编码特殊字符?

我想为我的标记系统以及所有特殊字符( + , & , # , % ,和=设置漂亮的URL。 有没有办法做到这一点与mod_rewrite,而不必对链接进行双重编码?

我注意到,delicIoUs.com和stackoverflow似乎能够处理单独编码的特殊字符。 什么是神奇的公式?

下面是我想要发生的一个例子:

http://www.foo.com/tag/c%2b%2b

会触发下面的RewriteRule:

什么是Bash Escape Character“ c”?

百分号在通过CALL传递时消失

使用相同的方式逃脱FileNames Bash做到这一点

在for循环中batch file调用转义redirect

在shell中转义字符

RewriteRule ^tag/(.*) script.PHP?tag=$1

标签的值将是“c ++”

apache / mod_rewrite的正常运行不能像这样工作,因为它似乎把加号转换为空格。 如果我将加号加倍编码为'%252B',那么我会得到所需的结果 – 但是这会造成杂乱的URLS,而且对我来说似乎很不好。

无法逃脱Windows的命令shell空间

在每个单词后添加逗号

使用参数从PowerShell启动batch file

简单的grep任何一年

为什么需要转义在Windows上文件path中使用的任何反斜杠

apache / mod_rewrite的正常运行不能像这样工作,因为它似乎把加号转换为空格。

我不认为这正是发生的事情。 Apache正在解码路径部分中的%2Bs到+ s,因为+在那里是有效的字符。 它在让mod_rewrite查看请求之前执行此操作。

那么mod_rewrite将你的请求'/ tag / c ++'改为'script.PHP?tag = c ++'。 但是在application / x-www-form-encoded格式的查询字符串组件中,转义规则与在路径部分中应用的转义规则略有不同。 特别是'+'是空格的缩写(也可以编成'%20',但这是一个我们现在永远无法改变的旧行为)。

所以PHP的表单阅读代码接收到'c ++'并将它作为C空间空间转储到_GET中。

看起来像这样的方式是使用重写标志'B'。 看到http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteflags – 好奇地它使用或多或少相同的例子!

RewriteRule ^tag/(.*)$ /script.PHP?tag=$1 [B]

我不确定我明白你在问什么,但是Apache的RewriteRule指令的NE (noescape)标志可能会对你有些兴趣。 基本上,它可以防止mod_rewrite自动转义您提供的替换模式中的特殊字符。 Apache 2.2文档中给出的例子是

RewriteRule /foo/(.*) /bar/arg=P1%3d$1 [R,NE]

例如/foo/zed转换成/bar/arg=P1%3dzed ,以便脚本/bar会看到一个名为arg的查询参数,其值为P1=zed ,如果它看起来在PATH_INFO (好吧,这不是一个真正的查询参数,所以告诉我; -P)。

至少,我认为这是如何工作的。 。 。 我从来没有用过那个特殊的标志。

我终于在RewriteMap的帮助下工作了。

在httpd.conf文件添加了转义映射RewriteMap es int:escape

并在重写规则中使用它

RewriteRule ([^?.]*) /abc?arg1=${es:$1}&country_sniff=true [L]

根本的问题是,您正在从具有一种编码(具体而言,加号是加号)的请求转变为具有不同编码的请求(加号表示空格)。 解决方法是绕过mod_rewrite所做的解码,然后直接从原始请求转换为查询字符串。

为了绕过重写规则的正常流程,我们将原始请求字符串直接加载到环境变量中,并修改环境变量而不是正常的重写路径。 它已经被编码了,所以当我们把它移动到查询字符串时,我们通常不需要担心编码。 然而,我们所要做的就是对加号进行百分比编码,以便将它们正确地转换为加号而不是空格。

规则非常简单:

RewriteEngine On RewriteRule ^script.PHP$ - [L] # Move the path from the raw request into _rq RewriteCond %{ENV:_rq} ="" RewriteCond %{THE_REQUEST} "^[^ ]+ (/path/[^/]+/[^? ]+)" RewriteRule .* - [E=_rq:%1] # encode the plus signs (%2B) (Loop with [N]) RewriteCond %{ENV:_rq} "/path/([^/]+)/(.*)+(.*)$" RewriteRule .* - [E=_rq:/path/%1/%2%2B%3,N] # finally,move it from the path to the query string # ([NE] says to not re-code it) RewriteCond %{ENV:_rq} "/path/([^/]+)/(.*)$" RewriteRule .* /path/script.PHP?%1=%2 [NE]

这个微不足道的script.PHP证实了它的工作原理:

<input readonly type="text" value="<?PHP echo $_GET['tag']; ?>" />

我遇到类似的问题mod_rewrite与+登录网址。 如下所示:

我们有一个带有+符号的网址需要重写,如http://deskdomain/2013/08/09/a+b+c.html

RewriteRule ^/(.*) http://mobiledomain/do/urlRedirect?url=http://%{HTTP_HOST}/$1

struts动作urlRedirect获取url参数,做一些更改并使用url进行另一次重定向。 但是在req.getParameter(“url”)中,+符号变为空,参数url内容是http://deskdomain/2013/08/09/ab c.html ,导致重定向404找不到。 为了解决它(从先前的答案中获得帮助),我们使用重写标志B(转义反向引用)和NE(noescape)

RewriteRule ^/(.*) http://mobiledomain/do/urlRedirect?url=http://%{HTTP_HOST}/$1 [B,NE]

B,将会跳转到%2B,NE会阻止mod_write转义%2B到%252B(double escape + sign),所以在req.getParameter("url")=http://deskdomain/2013/08/09/a+b+c.html

我认为原因是req.getParameter(“url”)会为我们做一个unescape,这个+符号可以使我的空白空白。 你可以尝试一次unescape%2B +,然后unescape +再次清空。

"%2B" unescape-> "+" unescape-> " "

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐