chuyển hướng htaccess sang https: // www


309

Tôi có mã htaccess sau:

<IfModule mod_rewrite.c>

RewriteEngine On
RewriteCond !{HTTPS} off
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

</IfModule>

Tôi muốn trang web của mình được chuyển hướng đến https://www.bằng HTTPS và thực thi www.tên miền phụ, nhưng khi tôi truy cập http://www.(không có HTTPS), nó không chuyển hướng tôi đến https://wwwbằng HTTPS.


Nên làRewriteCond %{HTTPS} =off
Michael Berkowski

1
Nếu tôi làm điều đó, nó sẽ chuyển hướng đến https: / / ww ww w w.
bigben

Gửi @bigben bạn đã chấp nhận một câu trả lời sai ở đây! bạn có thể tìm hiểu tại sao nó sai trong câu trả lời của tôi .
Amir cho

Câu trả lời:


632

Để bắt buộc HTTPS trước tiên, bạn phải kiểm tra biến môi trường chính xác %{HTTPS} off, nhưng quy tắc của bạn ở trên sau đó sẽ bổ sung www.Vì bạn có quy tắc thứ hai để thực thi www., không sử dụng quy tắc đầu tiên.

RewriteEngine On
RewriteCond %{HTTPS} off
# First rewrite to HTTPS:
# Don't put www. here. If it is already there it will be included, if not
# the subsequent rule will catch it.
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Now, rewrite any request to the wrong domain to use www.
# [NC] is a case-insensitive match
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

Về ủy quyền

Khi đứng sau một số hình thức ủy quyền, theo đó máy khách đang kết nối qua HTTPS với proxy, bộ cân bằng tải, ứng dụng Hành khách, v.v., %{HTTPS}biến có thể không bao giờ onvà gây ra vòng lặp viết lại. Điều này là do ứng dụng của bạn thực sự nhận được lưu lượng HTTP đơn giản mặc dù máy khách và bộ cân bằng proxy / tải đang sử dụng HTTPS. Trong những trường hợp này, hãy kiểm tra X-Forwarded-Prototiêu đề thay vì %{HTTPS}biến. Câu trả lời này cho thấy quá trình thích hợp


14
Trong một số trường hợp, chứng chỉ của bạn có thể chỉ tốt cho một tên miền (ví dụ, nó có thể hoạt động với www, nhưng, không phải không có). Trong những trường hợp như vậy, trước tiên hãy chuyển hướng đến tên miền chính xác, sau đó chuyển hướng đến https, nếu không bạn sẽ nhận được thông báo lỗi chứng nhận trong trình duyệt của mình.
Nick Benson

19
Khi tôi sử dụng RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]một URL như exaple.com/?bla=%20 đã trở thành exaple.com/?bla=%2520 , tức là dấu phần trăm đã được mã hóa. Cân nhắc sử dụng cờ NEđể ngăn mã hóa kép:RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
Đánh bại

5
cái này cho tôi một vòng lặp chuyển hướng trên một máy chủ, hoạt động trên một máy chủ khác. tôi thực sự không biết tại sao
user151496

4
@ user151496 Máy chủ bị lỗi có sử dụng bất kỳ loại ủy quyền HTTP nào không, như chuyển qua bộ đệm Varnish hoặc vào Hành khách? Nếu vậy, bạn có thể phải kiểm tra X-Forwarded-Prototiêu đề để xác minh HTTPS thay vì %{HTTPS}biến. Bạn đã không nói phần nào gây ra vòng lặp, wwwphần HTTPS, nhưng đó là điều đầu tiên tôi nghĩ đến.
Michael Berkowski

5
Nói đúng ra, hai quy tắc bạn có ở trên là sai thứ tự. Nếu một yêu cầu được gửi đến http://example.com(ví dụ: HTTP và không phải www) thì bạn sẽ nhận được chuyển hướng kép. Đầu tiên https://example.com(quy tắc đầu tiên) và sau đó đến https://www.example.com(quy tắc thứ hai). Bạn có thể khắc phục điều này bằng cách đơn giản đảo ngược hai quy tắc này, vì cả hai quy tắc đều chuyển hướng sang HTTPS bất kể.
MrWhite

148

Câu trả lời của Michals làm việc cho tôi, mặc dù với một sửa đổi nhỏ:

Vấn đề:

khi bạn có một chứng chỉ bảo mật trang web duy nhất , một trình duyệt cố gắng truy cập trang của bạn mà không có https: // www. (hoặc bất kỳ tên miền nào chứng chỉ của bạn bao gồm) sẽ hiển thị màn hình cảnh báo màu đỏ xấu xí trước khi nó nhận được chuyển hướng đến trang https an toàn và chính xác.

Giải pháp

Trước tiên, hãy sử dụng chuyển hướng đến www (hoặc bất kỳ tên miền nào được bao phủ bởi chứng chỉ của bạn) và chỉ sau đó thực hiện chuyển hướng https. Điều này sẽ đảm bảo rằng người dùng của bạn không phải đối mặt với bất kỳ lỗi nào vì trình duyệt của bạn nhìn thấy chứng chỉ không bao gồm url hiện tại.

#First rewrite any request to the wrong domain to use the correct one (here www.)
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

#Now, rewrite to HTTPS:
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

5
+1 vì đây là tùy chọn tốt hơn cho kịch bản này, nhưng lưu ý rằng điều này sẽ không ngăn vấn đề tương tự xảy ra nếu máy khách truy cập https://example.com, nhưng theo tôi đó là định dạng ít có khả năng nhất được người dùng nhập vào. (Câu trả lời được chấp nhận cũng sẽ có cùng một vấn đề)
Joshua Goossen

@Larzan: Đó là sai. Ngoại lệ chứng nhận chỉ xảy ra vì bạn thực hiện 2 lần chuyển hướng thực sự . Thay thế "[L, R = 301]" bằng "[R = 301]". Các quy tắc không được hủy bỏ. L = LAST
định

Nếu bạn cần xử lý https://mà không wwwcó chứng chỉ trong khi wwwchỉ cần thêm quy tắc này vào giải pháp: RewriteCond %{HTTP_HOST} !^www\. RewriteCond %{HTTPS} on RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI}[L,R=301] Đơn giản chỉ cần quay lại httpkhi cố gắng kết nối https://example.comđể tránh lỗi chứng chỉ.
Eric Burel

1
Hai quy tắc nên được đảo ngược bằng mọi cách (như bạn đã làm), để ngăn chặn chuyển hướng kép khi yêu cầu http://example.com(ví dụ: HTTP và không có www)
MrWhite

@EricBurel Bạn không thể tránh được lỗi cert trong trường hợp này - bắt tay SSL xảy ra trước khi mã của bạn thực thi (đó là toàn bộ điểm SSL ở vị trí đầu tiên). Nếu chuyển hướng của bạn có thể thực thi trước lỗi chứng chỉ trình duyệt thì điều đó có nghĩa là yêu cầu đã được thực hiện qua kết nối không an toàn - đó sẽ là một lỗi cơ bản trong mô hình SSL.
MrWhite

99

Nếu bạn đang sử dụng CloudFlare hoặc CDN tương tự, bạn sẽ gặp lỗi vòng lặp vô hạn với các giải pháp% {HTTPS} được cung cấp tại đây. Nếu bạn là người dùng CloudFlare, bạn sẽ cần sử dụng điều này:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

2
Vui lòng lưu ý lời khuyên hiện tại trên trang web hỗ trợ của Cloudflare hơi khác một chút: support.cloudflare.com/hc/en-us/articles/
mẹo

1
Đồng ý với @ h0mayun, lời khuyên Cloudflare đưa ra kết quả trong vòng lặp chuyển hướng, trong khi mã này ở đây hoạt động hoàn hảo - cảm ơn bạn!
hobailey 18/03/2015

2
Tôi chạy angularjs trên ec2. Các giải pháp sử dụng RewriteCond% {HTTPS}! = On cho tôi chuyển hướng vô hạn (không hoàn toàn chắc chắn tại sao). Giải pháp này, với X-Forwarded-Proto, dường như thực hiện thủ thuật. Cảm ơn bạn!
Mark Watkins

3
Tôi sửa đổi =httpđể !=httpscho các môi trường của chúng tôi. X-Forwarded-Prototiêu đề không được khai báo nếu http, !=httpslừa cũng vậy .
Johnathan Elmore

Cảm ơn bạn cho cái nhìn sâu sắc này! Tôi đã dành hàng giờ cố gắng để tìm ra lý do tại sao {HTTPS}không làm việc. Tôi đã thử {ENV:HTTPS}và thậm chí {SERVER_PORT} 443, nhưng cuối cùng là vì tôi cần kiểm tra các tiêu đề yêu cầu HTTP tùy chỉnh của Cloudflare.
camslice

56

GIẢI PHÁP BAD VÀ TẠI SAO!

Đừng bao giờ sử dụng giải pháp dưới đây vì khi bạn đang sử dụng mã của họ giống như:

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

RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.example.com%{REQUEST_URI} [L,R=301]

Trình duyệt đi đến:

http://example.com

Sau đó chuyển hướng đến:

https://example.com

Sau đó chuyển hướng đến:

https://www.example.com

Đây là quá nhiều yêu cầu đến máy chủ.

Hầu hết các câu trả lời thậm chí được chấp nhận có một vấn đề này.


GIẢI PHÁP TỐT NHẤT VÀ TRẢ LỜI

Mã này có một [OR]điều kiện để ngăn chặn các thay đổi kép tại url!

RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule (.*) https://www.example.com%{REQUEST_URI} [R=301,L]

3
"GIẢI PHÁP BAD VÀ TẠI SAO!" - Những quy tắc đó chỉ theo thứ tự sai. Đảo ngược hai quy tắc đó và nó sẽ chính xác - bạn sẽ chỉ nhận được một chuyển hướng chứ không phải hai.
MrWhite

4
Có, mã như đã đưa ra kết quả trong 2 lần chuyển hướng - Tôi không tranh cãi rằng - tất cả những gì tôi nói là bạn chỉ cần đảo ngược các quy tắc này để giải quyết vấn đề này, không cần thay đổi nào khác. (Câu trả lời "được chấp nhận" thực sự không chính xác - dường như là những gì bạn đang đề cập - các chỉ thị sai thứ tự.)
MrWhite

1
yup @AmirForsati đã đúng. nó đang chuyển hướng hai lần và đây sẽ là câu trả lời được chấp nhận.
Zakir hussain

4
Bạn có thể sử dụng điều này nếu bạn muốn giữ biến tên miền:RewriteEngine On RewriteCond %{HTTPS} off RewriteCond %{HTTP_HOST} !^www\. [NC] RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteCond %{HTTPS} off RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
I.devries

Điều này đang chuyển hướng tôi đến wp-content/cache/page_enhanced/và sau đó. Làm thế nào tôi có thể sửa lỗi này? Chỉnh sửa: Có vẻ như tôi cần đặt nó ở đầu .htaccess. Cảm ơn kịch bản :)
Giacomo

35

Đây là cách tốt nhất tôi tìm thấy cho Proxy và không phải người dùng proxy

RewriteEngine On

### START WWW & HTTPS

# ensure www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

### END WWW & HTTPS

2
Đúng Đây là cách tốt nhất tôi tìm thấy cho Proxy và không phải người dùng proxy +1
Sâu 3015

1
Đây là cách tốt nhất, vì nó giải quyết được nhiều chuyển hướng 301
Niraj Chauhan

1
giải pháp tốt nhất
SM Jobayer Alam

1
Câu trả lời chính xác. Đây là người duy nhất làm việc cho tôi. Hoạt động nếu bạn đứng sau Cloudflare (mặc dù tôi không có quy tắc trang nào được thiết lập tại Cloudflare).
jasonco

Giải pháp duy nhất hoạt động trên tất cả các trường hợp của tôi. Nhưng điều gì sẽ xảy ra nếu tôi muốn thực hiện và loại bỏ tất cả "www."
FedeKrum

27

Có rất nhiều giải pháp ra khỏi đó. Đây là một liên kết đến wiki apache liên quan đến vấn đề này trực tiếp.

http://wiki.apache.org/httpd/RewriteHTTPToHTTPS

RewriteEngine On
# This will enable the Rewrite capabilities

RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS

RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e.  http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context

Tôi tìm thấy bằng cách thay đổi các điều kiện ghi đè với tính RewriteCond %{HTTPS} offđể RewriteCond %{HTTPS} !=onchuyển hướng đó sẽ luôn luôn xảy ra, điều này dường như là câu trả lời tốt hơn cho tôi.
Samuel Hawksby-Robinson

Giải pháp này nên được chấp nhận như một câu trả lời chính xác! Làm việc cho tôi quá!
AndrewShmig

11

Để chuyển hướng http: // hoặc https: // sang https: // www, bạn có thể sử dụng quy tắc sau trên tất cả các phiên bản của apache:

RewriteEngine on

RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]

Apache 2.4

RewriteEngine on

RewriteCond %{REQUEST_SCHEME} http [OR]
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ https://www.example.com%{REQUEST_URI} [NE,L,R]

Lưu ý rằng biến% {REQUEST_SCHEME} có sẵn để sử dụng kể từ apache 2.4 .


1
Vấn đề!: Nếu HTTP_HOST đã có www. nhưng chương trình không phải là HTTPS, sau đó bạn kết thúc với www.www. trong máy chủ của bạn.
Jpsy

@Jpsy bạn nói đúng. Tôi đã cập nhật đích Redirect. Cảm ơn vì đầu vào của bạn.
starkeen

1
Đây gần như là những gì tôi đang tìm kiếm nhưng tôi muốn giữ tên miền chung như trong các ví dụ khác. Có thể không?
cronoklee

8

Nếu bạn đang ở trên CloudFlare, hãy đảm bảo bạn sử dụng một cái gì đó như thế này.

# BEGIN SSL Redirect
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
# END SSL Redirect

Điều này sẽ cứu bạn khỏi vòng lặp chuyển hướng và sẽ chuyển hướng trang web của bạn đến SSL một cách an toàn.

PS Nên kiểm tra mod_rewrite.c!


nó không chuyển hướng https: // theurlwithoutwww.com sang https: // www.
thesearentthedroids

Đây thực sự chỉ là giải pháp hiệu quả nếu bạn có một số chỉ thị "thêm www" trước đó. Các giải pháp khác mang lại cho tôi "nhiều chuyển hướng".
Daniel.P.

3
RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R]

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

Lưu ý: Đảm bảo bạn đã thực hiện các bước sau

  1. sudo a2enmod viết lại
  2. sudo dịch vụ apache2 khởi động lại
  3. Thêm Theo dõi trong tệp vhost của bạn, được đặt tại /etc/apache2/sites-av Available / 000-default.conf
<Directory /var/www/html>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride All
  Order allow,deny
  allow from all
  Require all granted
</Directory>

Bây giờ .htaccess của bạn sẽ hoạt động và trang web của bạn sẽ chuyển hướng đến http: // đến https: // www


1

Tương tự như giải pháp htaccess của Amir Forsati chuyển hướng sang https: // www nhưng đối với tên miền biến, tôi đề nghị:

RewriteEngine on
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%2%{REQUEST_URI} [R=301,L]

0

Đặt trong tệp .htaccess của bạn

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]


-2

Tôi thử câu trả lời đầu tiên và nó không hoạt động ... Công việc này:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /

RewriteCond %{ENV:HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.