Htaccess强制https除了一个网址不起作用

时间:2017-09-20 13:44:05

标签: .htaccess mod-rewrite zend-framework

我尝试将所有网站强制为https。所以我做了:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php

RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]

有效。问题是我希望mywebsite.com/api /上的http调用也能正常工作。所以我添加了RewriteCond %{REQUEST_URI} !^/api(/.*)?

我的.htaccess是:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php

RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !^/api(/.*)?
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]

但它不起作用。如果我致电http://mywebsite.com/api/xxx,我会将我重定向到https://mywebsite.com/index.php ..

我不知道为什么。你有什么想法吗? 我使用Zend 1

----编辑----

将我的.htaccess更改为:

RewriteEngine On

# HTTPS
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !^/api(/.*)?
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=302]

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php

Options +Indexes
IndexIgnore *

但仍然无效

----编辑2 ----

新的.htaccess(这个正在运作):

RewriteEngine On
RewriteBase /

# HTTPS
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
RewriteCond %{REQUEST_URI} !^/api
RewriteCond %{QUERY_STRING} !^/api
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [NC,L,QSA]

我必须使用QUERY_STRING添加条件,并将上次重定向更改为index.php

谢谢@MrWhite

2 个答案:

答案 0 :(得分:4)

您的指令顺序错误。您的规范HTTP到HTTPS重定向应该在您的内部重写之前(即您的前端控制器)。否则,/api/<something>的请求将在内部重写为/index.php(因为我认为/api/<something>不存在为真实文件)。 /index.php然后将与检查RewriteCond的{​​{1}}指令不匹配。因此,您可以重定向/api/<something>(虽然您的示例中已经提供了https://example.com/index.php。)。

  

不在代理

之后

如果您不在代理服务器后面,那么您应该删除检查http HTTP请求标头的条件(这些只由代理服务器设置,如果您不在代理服务器后面,那么客户端可能会恶意设置此标头并避免重定向。)

这两行:

X-Forwarded-Proto

UPDATE:如果在删除上述条件后获得重定向循环,那么可能是你毕竟在SSL代理后面(你应该能够通过检查HTTP请求标题告诉你应用程序看到 - 您不一定需要访问服务器配置 - 实际上,您可能无法通过查看服务器配置来判断。)

(当您在SSL代理后面时,RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR] RewriteCond %{HTTP:X-Forwarded-Proto} ="" 总是HTTPS - 您的应用程序向SSL代理提供HTTP响应,然后将加密的HTTPS响应提供给客户端。)

尝试以下方法:

off

请注意,这并非规范化www与非www。

答案 1 :(得分:2)

无论您的代码如何,只需将以下代码放在主目录.htaccess文件中:

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{THE_REQUEST} !\s/+api/ [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R]

如果您使用api/httpshttphttp请求您的网站/ api,则会强制除www以外的所有请求为www 1}}它将转到api/目录,因为api/https以及www不是https问题,上述规则将不适用于RewriteCond %{HTTPS} !=on由于这种情况http://yourwebsite/api所以如果有这个,它会覆盖该规则以及为什么https://yourwebsite/api<ListView ItemsSource="{Binding WorkItems}" > <ListView.View> <GridView> <GridViewColumn> <GridViewColumn.CellTemplate> <DataTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="70"/> <ColumnDefinition Width="850"/> </Grid.ColumnDefinitions> /* Display properties from Work Item */ <TextBox Grid.Row="0" Grid.Column="0" Text="{Binding Code}" /> /* This SelectedItem works sometimes, but not all the time */ <ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding Tasks}" SelectedItem="{Binding Path=DataContext.SelectedTask, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" > <ListBox.ItemTemplate> <DataTemplate> <Grid Margin="0,0,0,5"> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <StackPanel Grid.Row="0" Orientation="Horizontal"> /* Display properties from Work Item Task */ <TextBlock Text="{Binding Path=Description}" /> </StackPanel> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView> 会起作用