htaccess เปลี่ยนเส้นทางไปที่ https: // www


309

ฉันมีรหัส htaccess ต่อไปนี้:

<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>

ฉันต้องการให้มีการเปลี่ยนเส้นทางเว็บไซต์ของฉันhttps://www.ด้วย HTTPS และบังคับใช้www.โดเมนย่อย แต่เมื่อฉันเข้าถึงhttp://www.(โดยไม่มี HTTPS) จะไม่เปลี่ยนเส้นทางฉันไปที่https://wwwHTTPS


ควรเป็นRewriteCond %{HTTPS} =off
Michael Berkowski

1
หากฉันทำเช่นนั้นจะเปลี่ยนเส้นทางไปที่https: / / ww ww w w
bigben

เรียน @bigben คุณยอมรับคำตอบที่ผิดที่นี่! คุณสามารถหาเหตุผลที่ไม่ถูกต้องในของฉันคำตอบ
Amir Fo

คำตอบ:


632

ในการบังคับใช้ HTTPS อันดับแรกคุณต้องตรวจสอบตัวแปรสภาพแวดล้อมที่ถูกต้อง%{HTTPS} offแต่กฎของคุณด้านบนนั้นเป็นการเตรียมการwww.เนื่องจากคุณมีกฎข้อที่สองที่จะบังคับใช้www.อย่าใช้ในกฎข้อแรก

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]

เกี่ยวกับพร็อกซี่

เมื่ออยู่เบื้องหลังการพร็อกซีบางรูปแบบโดยที่ไคลเอ็นต์กำลังเชื่อมต่อผ่าน HTTPS ไปยังพร็อกซี, โหลดบาลานเซอร์, แอปพลิเคชันผู้โดยสาร ฯลฯ%{HTTPS}ตัวแปรอาจไม่เคยเป็นonและทำให้เกิดการเขียนซ้ำลูป นี่เป็นเพราะแอปพลิเคชันของคุณได้รับการรับส่งข้อมูล HTTP ธรรมดาแม้ว่าไคลเอนต์และพร็อกซี / โหลดบาลานเซอร์กำลังใช้ HTTPS ในกรณีเหล่านี้ตรวจสอบX-Forwarded-Protoส่วนหัวแทน%{HTTPS}ตัวแปร คำตอบนี้แสดงกระบวนการที่เหมาะสม


14
ในบางกรณีใบรับรองของคุณอาจดีสำหรับโดเมนเดียว (อาจทำงานกับ www ได้ แต่ไม่ใช่โดยไม่มี) ในกรณีดังกล่าวให้เปลี่ยนเส้นทางไปยังโดเมนที่ถูกต้องก่อนจากนั้นจึงเปลี่ยนเส้นทางไปที่ https มิฉะนั้นคุณจะได้รับข้อความแสดงข้อผิดพลาดใบรับรองในเบราว์เซอร์ของคุณ
Nick Benson

19
เมื่อฉันใช้RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]URL เช่นexaple.com/?bla=%20กลายเป็นexaple.com/?bla=%2520นั่นคือมีการเข้ารหัสเครื่องหมายเปอร์เซ็นต์ ลองใช้การตั้งค่าสถานะNEเพื่อป้องกันการเข้ารหัสสองครั้ง:RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [NE,L,R=301]
เอาชนะ

5
สิ่งนี้ทำให้ฉันมีการวนรอบการเปลี่ยนเส้นทางบนเซิร์ฟเวอร์หนึ่งทำงานบนเซิร์ฟเวอร์อื่น ฉันไม่รู้จริงๆว่าทำไม
user151496

4
@ user151496 เซิร์ฟเวอร์ที่ล้มเหลวใช้ HTTP proxying ชนิดใดก็ได้เช่นการผ่านแคช Varnish หรือไปสู่ ​​Passenger หรือไม่ ถ้าเป็นเช่นนั้นคุณอาจต้องตรวจสอบX-Forwarded-Protoส่วนหัวเพื่อตรวจสอบ HTTPS แทน%{HTTPS}ตัวแปร คุณไม่ได้บอกว่าส่วนใดเป็นสาเหตุของลูปส่วนwwwหรือส่วน HTTPS แต่นั่นเป็นสิ่งแรกที่นึกถึงฉัน
Michael Berkowski

5
พูดอย่างเคร่งครัดกฎทั้งสองข้อที่คุณมีอยู่ในลำดับที่ไม่ถูกต้อง หากคำขอมาสำหรับhttp://example.com(เช่น HTTP และไม่ใช่ www) คุณจะได้รับการเปลี่ยนเส้นทางสองครั้ง ก่อนถึงhttps://example.com(กฎข้อแรก) จากนั้นถึงhttps://www.example.com(กฎข้อที่สอง) คุณสามารถแก้ไขได้โดยเพียงแค่ย้อนกลับกฎทั้งสองนี้เนื่องจากกฎทั้งสองเปลี่ยนเส้นทางไปที่ HTTPS โดยไม่คำนึงถึง
MrWhite

148

คำตอบของ Michals เหมาะกับฉันแม้ว่าจะมีการดัดแปลงเพียงเล็กน้อย:

ปัญหา:

เมื่อคุณมีใบรับรองความปลอดภัยของไซต์เดียวเบราว์เซอร์ที่พยายามเข้าถึงหน้าของคุณโดยไม่มี https: // www (หรือโดเมนใดที่ครอบคลุมใบรับรองของคุณ) จะแสดงหน้าจอคำเตือนสีแดงน่าเกลียดก่อนที่จะได้รับการเปลี่ยนเส้นทางไปยังหน้า https ที่ปลอดภัยและถูกต้อง

สารละลาย

ก่อนอื่นให้ใช้การเปลี่ยนเส้นทางไปที่ www (หรือโดเมนใดก็ตามที่ครอบคลุมโดยใบรับรองของคุณ) จากนั้นทำการเปลี่ยนเส้นทาง https เท่านั้น วิธีนี้จะช่วยให้มั่นใจได้ว่าผู้ใช้ของคุณจะไม่พบข้อผิดพลาดใด ๆ เนื่องจากเบราว์เซอร์ของคุณเห็นใบรับรองที่ไม่ครอบคลุม URL ปัจจุบัน

#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 เนื่องจากเป็นตัวเลือกที่ดีกว่าสำหรับสถานการณ์นี้ แต่โปรดทราบว่าสิ่งนี้จะไม่ป้องกันปัญหาเดียวกันที่เกิดขึ้นหากลูกค้าเข้าถึงhttps://example.comแต่ในความคิดเห็นของฉันว่าเป็นรูปแบบที่ผู้ใช้พิมพ์น้อยที่สุด (คำตอบที่ได้รับการยอมรับจะมีปัญหาเดียวกัน)
Joshua Goossen

@ Larzan: นั่นผิดนะ ข้อยกเว้นใบรับรองเกิดขึ้นเพียงเพราะคุณเปลี่ยนเส้นทางจริง 2 ครั้ง แทนที่ "[L, R = 301]" ด้วย "[R = 301]" กฎเหล่านี้จะไม่ถูกยกเลิก L = LAST
defim

หากคุณต้องการจัดการhttps://โดยไม่ต้องwwwมีใบรับรองเพียงอย่างเดียวในwwwเพียงเพิ่มกฎนี้ลงในโซลูชัน: RewriteCond %{HTTP_HOST} !^www\. RewriteCond %{HTTPS} on RewriteRule ^(.*)$ http://www.%{HTTP_HOST}%{REQUEST_URI}[L,R=301] มันจะกลับไปhttpเมื่อพยายามเชื่อมต่อhttps://example.comเพื่อหลีกเลี่ยงข้อผิดพลาดใบรับรอง
Eric Burel

1
ควรย้อนกลับกฎทั้งสองต่อไป (ตามที่คุณทำ) เพื่อป้องกันการเปลี่ยนเส้นทางสองครั้งเมื่อมีการร้องขอhttp://example.com(เช่น HTTP และไม่มี www)
MrWhite

@EricBurel คุณไม่สามารถหลีกเลี่ยงข้อผิดพลาดใบรับรองในกรณีนี้ - การจับมือ SSL เกิดขึ้นก่อนที่โค้ดของคุณจะทำงาน (ซึ่งเป็นจุดรวมของ SSL ในตอนแรก) หากการเปลี่ยนเส้นทางของคุณสามารถดำเนินการก่อนที่ข้อผิดพลาดของใบรับรองเบราว์เซอร์ก็หมายความว่ามีการร้องขอผ่านการเชื่อมต่อที่ไม่ปลอดภัยซึ่งจะเป็นความล้มเหลวพื้นฐานในรูปแบบ SSL
MrWhite

99

หากคุณกำลังใช้ CloudFlare หรือ CDN ที่คล้ายกันคุณจะได้รับข้อผิดพลาดวนซ้ำไม่สิ้นสุดพร้อมกับโซลูชัน% {HTTPS} ที่ให้ไว้ที่นี่ หากคุณเป็นผู้ใช้ CloudFlare คุณจะต้องใช้สิ่งนี้:

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

2
โปรดทราบว่าคำแนะนำในปัจจุบันบนเว็บไซต์สนับสนุน Cloudflare นั้นแตกต่างกันเล็กน้อย: support.cloudflare.com/hc/en-us/articles/…
ColinMcDermott

1
เห็นด้วยกับ @ h0mayun คำแนะนำ Cloudflare ให้ผลลัพธ์ในการวนรอบการเปลี่ยนเส้นทางในขณะที่รหัสนี้ทำงานได้อย่างสมบูรณ์ - ขอบคุณ!
hobailey

2
ฉันเรียกใช้ angularjs บน ec2 โซลูชันที่ใช้ RewriteCond% {HTTPS}! = ให้การเปลี่ยนเส้นทางแบบไม่สิ้นสุด วิธีแก้ปัญหานี้เมื่อใช้ X-Forwarded-Proto ขอบคุณ!
Mark Watkins

3
ฉันปรับเปลี่ยน=httpเป็น!=httpsสำหรับสภาพแวดล้อมของเรา X-Forwarded-Protoส่วนหัวไม่ได้รับการประกาศถ้า http ดังนั้น!=httpsเคล็ดลับ
Johnathan Elmore

ขอบคุณสำหรับข้อมูลเชิงลึกนี้! ฉันใช้เวลาหลายชั่วโมงพยายามคิดว่าทำไม{HTTPS}ไม่ทำงาน ฉันพยายาม{ENV:HTTPS}และแม้กระทั่ง{SERVER_PORT} 443แต่ในท้ายที่สุดแล้วมันเป็นเพราะผมจำเป็นต้องมีการตรวจสอบของ CloudFlare หัวคำขอ HTTP ที่กำหนดเอง
camslice

56

วิธีแก้ปัญหาที่ไม่ดีและทำไม!

ไม่เคยใช้วิธีแก้ปัญหาด้านล่างเพราะเมื่อคุณใช้รหัสของพวกเขาที่เป็นเช่น:

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]

เบราว์เซอร์ไปที่:

http://example.com

จากนั้นเปลี่ยนเส้นทางไปที่:

https://example.com

จากนั้นเปลี่ยนเส้นทางไปที่:

https://www.example.com

นี่เป็นคำขอไปยังเซิร์ฟเวอร์มากเกินไป

คำตอบส่วนใหญ่ที่ยอมรับก็มีปัญหานี้


ทางออกที่ดีที่สุดและคำตอบ

รหัสนี้มี[OR]เงื่อนไขในการป้องกันการเปลี่ยนแปลงสองอย่างที่ url!

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

3
"วิธีแก้ไขปัญหาที่ไม่ดีและทำไม!" - กฎเหล่านั้นอยู่ในลำดับที่ผิด ย้อนกลับกฎสองข้อนั้นและจะถูกต้องคุณจะได้รับการเปลี่ยนเส้นทางเพียงครั้งเดียวและไม่ใช่สองกฎ
MrWhite

4
ใช่รหัสตามผลลัพธ์ที่ได้รับใน 2 การเปลี่ยนเส้นทาง - ฉันไม่ได้โต้แย้งว่า - ทั้งหมดที่ฉันพูดคือคุณเพียงแค่ย้อนกลับกฎเหล่านี้เพื่อแก้ไขปัญหานี้ไม่จำเป็นต้องมีการเปลี่ยนแปลงอื่น ๆ (คำตอบ "ยอมรับ" นั้นไม่ถูกต้อง - ซึ่งดูเหมือนจะเป็นสิ่งที่คุณอ้างถึง - คำสั่งนั้นอยู่ในลำดับที่ผิด)
MrWhite

1
yup @AmirForsati ถูกต้อง มันกำลังเปลี่ยนเส้นทางสองครั้งและนี่ควรเป็นคำตอบที่ยอมรับได้
Zakir hussain

4
คุณสามารถใช้สิ่งนี้หากคุณต้องการเก็บตัวแปรโดเมน: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

นี่คือการเปลี่ยนเส้นทางฉันไปwp-content/cache/page_enhanced/และอื่น ๆ ฉันจะแก้ไขสิ่งนี้ได้อย่างไร แก้ไข: .htaccessดูเหมือนว่าฉันจะต้องใส่ไว้ที่ด้านบนของ ขอบคุณสำหรับสคริปต์ :)
Giacomo

35

นี่เป็นวิธีที่ดีที่สุดที่ฉันพบสำหรับ 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
ถูกต้อง นี่เป็นวิธีที่ดีที่สุดที่ฉันพบสำหรับพรอกซีไม่ใช่ผู้ใช้พรอกซี +1
Deep 3015

1
นี่เป็นวิธีที่ดีที่สุดเนื่องจากสามารถแก้ไขการเปลี่ยนเส้นทาง 301 ครั้งได้หลายครั้ง
Niraj Chauhan

1
ทางออกที่ดีที่สุด
SM Jobayer Alam

1
คำตอบที่ดี นี่เป็นคนเดียวที่ทำงานให้ฉัน ใช้งานได้หากคุณอยู่หลัง Cloudflare (แม้ว่าฉันจะไม่มีกฎของหน้าตั้งค่าที่ Cloudflare)
jasonco

ทางออกเดียวที่ใช้ได้กับทุกกรณีของฉัน แต่ถ้าฉันต้องการทำ de oposite และลบ "www." ทั้งหมด
FedeKrum

27

มีทางออกมากมายที่นั่น นี่คือลิงค์ไปสู่ ​​apache wiki ซึ่งเกี่ยวข้องกับปัญหานี้โดยตรง

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

ฉันพบโดยการเปลี่ยนเงื่อนไขการเขียนใหม่จาก RewriteCond %{HTTPS} offเป็นการRewriteCond %{HTTPS} !=onเปลี่ยนเส้นทางนั้นจะเกิดขึ้นเสมอนี่เป็นคำตอบที่ดีกว่าสำหรับฉัน
ซามูเอลฮอว์คบี้ - โรบินสัน

คำตอบนี้ควรได้รับการยอมรับว่าเป็นคำตอบที่ถูกต้อง! ทำงานให้ฉันด้วย!
AndrewShmig

11

ในการเปลี่ยนเส้นทางhttp: //หรือhttps: //ไปยังhttps: // wwwคุณสามารถใช้กฎต่อไปนี้กับ 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]

ทราบว่าตัวแปร% {} REQUEST_SCHEME สามารถใช้ได้สำหรับการใช้งานตั้งแต่ Apache 2.4


1
ปัญหา!: ถ้า HTTP_HOST มี www อยู่แล้ว แต่รูปแบบไม่ใช่ HTTPS จากนั้นคุณจะจบด้วย www.www ในโฮสต์ของคุณ
Jpsy

@Jpsy คุณถูกต้อง ฉันได้อัปเดตปลายทางการเปลี่ยนเส้นทางแล้ว ขอบคุณสำหรับข้อมูลของคุณ
starkeen

1
นี่เป็นสิ่งที่ฉันกำลังมองหา แต่ฉันต้องการเก็บโดเมนทั่วไปไว้ในตัวอย่างอื่น ๆ เป็นไปได้ไหม?
cronoklee

8

หากคุณอยู่บน CloudFlare ตรวจสอบให้แน่ใจว่าคุณใช้สิ่งนี้

# 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

วิธีนี้จะช่วยให้คุณประหยัดจากวงวนการเปลี่ยนเส้นทางและจะเปลี่ยนเส้นทางไซต์ของคุณเป็น SSL อย่างปลอดภัย

ปล. เป็นความคิดที่ดีถ้าตรวจสอบ mod_rewrite.c!


มันไม่ได้เปลี่ยนเส้นทาง https: // theurlwithoutwww.com เป็น https: // www
thesearentthedroids

นี่เป็นวิธีแก้ปัญหาที่ใช้งานได้จริงหากคุณมีคำสั่ง "เพิ่ม www" ไว้ล่วงหน้า โซลูชันอื่น ๆ ทำให้ฉัน "เปลี่ยนเส้นทางหลายครั้ง"
Daniel.P


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

หมายเหตุ: ตรวจสอบให้แน่ใจว่าคุณได้ทำตามขั้นตอนต่อไปนี้แล้ว

  1. sudo a2enmod เขียนใหม่
  2. sudo service apache2 เริ่มต้นใหม่
  3. เพิ่มการติดตามในไฟล์ vhost ของคุณอยู่ที่ /etc/apache2/sites-available/000-default.conf
<Directory /var/www/html>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride All
  Order allow,deny
  allow from all
  Require all granted
</Directory>

ตอนนี้. htaccess ของคุณจะใช้งานได้และเว็บไซต์ของคุณจะเปลี่ยนเส้นทางไปที่ http: // ไปยังhttps: // www


1

คล้ายกับโซลูชันของ Amir Forsati เปลี่ยนเส้นทางไปยัง htaccess เพื่อ https: // wwwแต่สำหรับชื่อโดเมนตัวแปรฉันขอแนะนำ:

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

ตั้งในไฟล์. htaccess ของคุณ

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]

0

ฉันใช้โค้ดด้านล่างจากเว็บไซต์นี้มันใช้งานได้ดีhttps://www.freecodecamp.org/news/how-to-redirect-http-to-https-using-htaccess/

RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R,L]

หวังว่ามันจะช่วย


-2

ฉันลองตอบครั้งแรกแล้วมันใช้งานไม่ได้ ... งานนี้:

<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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.