.htaccess mod_rewrite捕获所有卡在循环中

时间:2016-12-30 01:36:20

标签: php regex apache .htaccess mod-rewrite

我有一个.htaccess文件,我正在尝试重写以下内容:

myserver.com/path1/path2 / - >的 myserver.com/?customer=path1&portal=path2

然后捕获所有其他不是文件,目录或符号链接的内容,以转到服务器的根目录,例如myserver.com /

我原以为myserver.com/?customer=path1&portal=path2会被检测为一个文件,即index.php,它是服务器的根目录,还是将其抛弃的查询字符串?

有谁能告诉我为什么这是无限循环以及如何解决?

RewriteEngine On
RewriteBase /
RewriteCond %{SERVER_PORT} !443
RewriteRule ^(.*)?$ https://%{HTTP_HOST}/$1 [L,R=301]
RewriteRule ^([^/]*)/([^/]*)/$ /?customer=$1&portal=$2 [L,R]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ / [L,R=301]

修改

我刚试过以下

RewriteRule ([^/]*)/$ https://%{HTTP_HOST}/?customer=$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ / [L,R=301]

现在

http://myserver.com/path1/

重定向至:

https://myserver.com/?customer=path1

然而

https://myserver.com/path1/

重定向至:

http://myserver.com/

那为什么https导致规则不匹配?

2 个答案:

答案 0 :(得分:0)

只有在尝试使用端口#443时,才会传递第一个条件。

然后下面的RewriteCond似乎没有完全按照你想要的那样做,你可以试试这个:RewriteRule ([^/]*)/([^/]*)/$ /?customer=$1&portal=$2 [L,R]。 所以基本上它只是删除字符串匹配^的开头。

您可以在此处使用非常好的工具进行尝试:http://htaccess.mwl.be/

RewriteEngine On
RewriteBase /
RewriteCond %{SERVER_PORT} !443
RewriteRule ^(.*)?$ https://%{HTTP_HOST}/$1 [L,R=301]
RewriteRule ([^/]*)/([^/]*)/$ /?customer=$1&portal=$2 [L,R]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ / [L,R=301]

<强> [编辑]

尝试将您的问题分离为一个简单的示例:

<强>的.htaccess

RewriteEngine On
RewriteBase /
RewriteCond %{SERVER_PORT} !80
RewriteRule ^(.*)?$ https://%{HTTP_HOST}/$1 [L,R=301]

RewriteRule ([^/]*)/([^/]*)/$ /?customer=$1&portal=$2 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ / [L,R=301]

<强>的index.php

<?php
print_r($_SERVER);

现在在浏览器中:view-source:http://localhost/path1/path3/将输出:

Array
(
    [REDIRECT_STATUS] => 200
    [HTTP_HOST] => localhost
    [HTTP_CONNECTION] => keep-alive
    [SERVER_NAME] => localhost
    [SERVER_ADDR] => ::1
    [SERVER_PORT] => 80
    [REMOTE_ADDR] => ::1
    ....
    [REMOTE_PORT] => 57976
    [REDIRECT_URL] => /path1/path3/
    [REDIRECT_QUERY_STRING] => customer=path1&portal=path3
    [GATEWAY_INTERFACE] => CGI/1.1
    [SERVER_PROTOCOL] => HTTP/1.1
    [REQUEST_METHOD] => GET
    [QUERY_STRING] => customer=path1&portal=path3
    [REQUEST_URI] => /path1/path3/
    [SCRIPT_NAME] => /index.php
    [PHP_SELF] => /index.php
    [REQUEST_TIME_FLOAT] => 1483066179.854
    [REQUEST_TIME] => 1483066179
)
  

[QUERY_STRING] => customer=path1&portal=path3

您不应该使用重定向,因为查询字符串已经是您想要的。 在此示例中,重定向不会永远循环。

答案 1 :(得分:0)

有这样的话:

RewriteEngine On
RewriteBase /

RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]

## If the request is for a valid directory
RewriteCond %{REQUEST_FILENAME} -d [OR]
## If the request is for a valid file
RewriteCond %{REQUEST_FILENAME} -f [OR]
## If the request is for a valid link
RewriteCond %{REQUEST_FILENAME} -l
## don't do anything
RewriteRule ^ - [L]

RewriteRule ^([^/]+)/([^/]+)/?$ ?customer=$1&portal=$2 [L,QSA]

RewriteRule . / [L,R=301]

确保在测试此更改之前清除浏览器缓存。