从请求的URI中删除查询字符串和index.php

时间:2017-05-23 01:39:53

标签: apache .htaccess redirect mod-rewrite internationalization

我有一个国际化的网站,其结构是:

English:   /(.*)
Spanish:   /es/(.*)
French:    /fr/(.*)
Chinese:   /zh/(.*)

例如,关于我们的页面将是:

English:   /aboutus/
Spanish:   /es/aboutus/
French:    /fr/aboutus/
Chinese:   /zh/aboutus/

所有子目录都是真正的子目录,所有请求都被重写回该子目录中的index.php文件,并附加一个GET变量lang=xx以发送给PHP。

例如:

RewriteCond %{QUERY_STRING} ([^=]*)=(.*)
RewriteRule ^es/(.*/)?$ $1/index.php?lang=es&%1=%2 [NC,L]
RewriteRule ^es/(.*/)?$ $1/index.php?lang=es [NC,L]

这似乎工作得很好,除了某种程度,在某个地方,我有另一个错误,谷歌使用实际重写的网址索引我的整个网站,如:

https://www.example.com/aboutus/index.php?lang=fr

然后搞砸了我网站的另一部分,以及创建重复的内容。我可以通过删除index.php来部分修复它,如下所示:

RewriteCond %{THE_REQUEST} index.php
RewriteRule ^(.*)?index.php$ /$1 [L,R=301]

但是,如果我尝试删除查询字符串:

RewriteCond %{QUERY_STRING} ^lang=es$
RewriteCond %{THE_REQUEST} !^/?es(.*)?$
RewriteCond %{REQUEST_URI} !^/?es(.*)?$
RewriteRule (.*) /es/$1? [R=301,L]
然后,我在我想要的内容之间得到一个无限循环,并将index.php附加到它上面:

$ curl -I -L https://www.example.com/aboutus/index.php?lang=es
HTTP/1.1 301 Moved Permanently
Date: Tue, 23 May 2017 01:13:19 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Location: https://www.example.com/aboutus/?lang=es
Vary: Accept-Encoding
Content-Type: text/html; charset=iso-8859-1

HTTP/1.1 301 Moved Permanently
Date: Tue, 23 May 2017 01:13:19 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Location: https://www.example.com/es/aboutus/
Vary: Accept-Encoding
Content-Type: text/html; charset=iso-8859-1

HTTP/1.1 301 Moved Permanently
Date: Tue, 23 May 2017 01:13:19 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Location: https://www.example.com/es/aboutus/index.php
Vary: Accept-Encoding
Content-Type: text/html; charset=iso-8859-1

HTTP/1.1 301 Moved Permanently
Date: Tue, 23 May 2017 01:13:19 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Location: https://www.example.com/es/aboutus/
Vary: Accept-Encoding
Content-Type: text/html; charset=iso-8859-1

HTTP/1.1 301 Moved Permanently
Date: Tue, 23 May 2017 01:13:19 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Location: https://www.example.com/es/aboutus/index.php
Vary: Accept-Encoding
Content-Type: text/html; charset=iso-8859-1

HTTP/1.1 301 Moved Permanently
Date: Tue, 23 May 2017 01:13:19 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Location: https://www.example.com/es/aboutus/
Vary: Accept-Encoding
Content-Type: text/html; charset=iso-8859-1

我还尝试删除规则中的最后一个?,这也不是很有效,但至少我没有循环:

RewriteCond %{QUERY_STRING} ^lang=es$
RewriteCond %{THE_REQUEST} !^/?es(.*)?$
RewriteCond %{REQUEST_URI} !^/?es(.*)?$
RewriteRule (.*) /es/$1 [R=301,L]

结果:

$ curl -I -L https://www.example.com/aboutus/index.php?lang=es
HTTP/1.1 301 Moved Permanently
Date: Tue, 23 May 2017 01:18:31 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Location: https://www.example.com/aboutus/?lang=es
Vary: Accept-Encoding
Content-Type: text/html; charset=iso-8859-1

HTTP/1.1 301 Moved Permanently
Date: Tue, 23 May 2017 01:18:31 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Location: https://www.example.com/es/aboutus/?lang=es
Vary: Accept-Encoding
Content-Type: text/html; charset=iso-8859-1

HTTP/1.1 200 OK
Date: Tue, 23 May 2017 01:18:31 GMT
Server: Apache
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Set-Cookie: PHPSESSID=pv84bbm3fropancqpcrmkle6h1; path=/; domain=.example.com; secure; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Vary: Accept-Encoding
Content-Type: text/html; charset=utf-8

我尝试将上面的最后一个与:

结合起来
RewriteCond %{QUERY_STRING} lang=es
RewriteCond %{REQUEST_URI} ^/?es(.*)?$
RewriteRule (.*) /es/$1? [R=301,L]

然而,这条规则似乎没有任何效果。

我必须要亲近。

1 个答案:

答案 0 :(得分:1)

将问题重新发送到问题的开头,即https://www.example.com/aboutus/index.php?lang=fr等Google索引网址,您应该有一条规则来一步修正

# Redirect /some-path/index.php?lang=fr to /fr/some-path/ (same for es and zh)
RewriteCond %{THE_REQUEST} \s/(.*)/?index\.php\?lang=(fr|es|zh)\s [NC]
RewriteRule ^ /%2/%1? [R=301,L]

# Redirect /some-path/index.php?lang=en to /some-path/
RewriteCond %{THE_REQUEST} \s/(.*)/?index\.php\?lang=en\s [NC]
RewriteRule ^ /%1? [R=301,L]

注意:在尝试之前不要忘记清除浏览器的缓存(否则您的旧规则可能会干扰,而中间案例将不符合上述规则)