เหตุใดฉันจึงได้รับเครื่องหมายทับสองด้านโดยขึ้นอยู่กับว่า RewriteRule ของฉันอยู่ที่ใด


9

ฉันใช้รหัสต่อไปนี้เพื่อนำคำร้องขอ www ทั้งหมดไปยัง URL ที่ไม่ใช่ www:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

สิ่งนี้ใช้งานได้ดีในไฟล์. htaccess ในรูทของเว็บไซต์ของฉัน
ตัวอย่างเช่น
www.example.com -> example.com/
www.example.com/ -> example.com/
www.example.com/other_page -> example.com/other_page

อย่างไรก็ตามหากฉันย้ายรหัสเดียวกันนี้ไปยังการกำหนดค่า VirtualHost ของฉัน URL ที่เขียนใหม่จะมีเครื่องหมายทับสองด้าน
www.example.com -> example.com//
www.example.com/ -> example.com //
www.example.com/other_page -> example.com//other_page

ฉันแก้ไขได้โดยลบเครื่องหมายทับจากกฎการเขียนซ้ำ:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com$1 [R=301,L]

แต่ฉันไม่เข้าใจเหตุผลนี้ ใครรู้ว่าทำไม

คำตอบ:


10

ตามที่ฉันเข้าใจแล้วในไฟล์. htaccess สตริงที่กระบวนการ mod_rewrite ในกฎของคุณสัมพันธ์กับไดเรกทอรีที่ไฟล์. htaccess อยู่ดังนั้นจะไม่มี a / at start

ในรายการ VirtualHost สตริงที่ดำเนินการจะเป็นรูทของเซิร์ฟเวอร์และรวมถึง /

มันทำให้ความแตกต่างเล็กน้อยในวิธีการทำงานของ mod_rewrite

นี่คือคนที่มีปัญหาที่คล้ายกันและวิธีแก้ไข:

http://forum.modrewrite.com/viewtopic.php?p=56322&sid=77f72967f59200b5b5de174440234c3a

สิ่งนี้ควรใช้งานได้ทั้งสองกรณีโดยสมมติว่าฉันจำได้ว่าการหลบหนีถูกต้อง

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^\/?(.*?)$ http://example.com/$1 [R=301,L]

ขอบคุณ! ตอนนี้ฉันเข้าใจแล้วว่าทำไมอย่างน้อย อย่างไรก็ตามนี่เป็นเหตุผลที่ดีกว่าการลบ / ก่อนที่จะ $ 1 เหมือนที่ฉันแสดงในคำถามเดิมของฉันหรือไม่
davekaro

1
ไม่ดีหรือแย่กว่านั้นมันเป็นเพียงแค่บล็อกที่คุณสามารถสลับระหว่าง. htaccess ของ VirtualHost โดยไม่ต้องแก้ไขแต่ละครั้งเพื่อจัดการกับความแตกต่างของบริบท หากวิธีการของคุณทำงานให้คุณติดกับมัน! :)
Neobyte

โอ้ถูกต้อง - วิธีการของคุณจะใช้ได้ทั้ง. htaccess และ VirtualHost ที่ทำให้มันได้ดี IMO :)
davekaro

4
ฉันมีปัญหาเดียวกันกับ @davkaro และลองวิธีแก้ปัญหาของคุณ บรรทัดสุดท้ายใช้งานไม่ได้สำหรับฉัน RewriteRule ^/?(.*)$ http://example.com/$1 [R=301,L]ทำเคล็ดลับ
Kenny Rasschaert

2

มันเกิดขึ้นเพราะคุณจับเฉือนเริ่มต้นด้วยแล้วใช้เฉือนอื่นก่อนที่มันจะอยู่ในสถานที่ใหม่(.*) /$1มันไม่ได้เกิดขึ้นมาก่อนเพราะ mod_rewrite มีพฤติกรรมแตกต่างกันเล็กน้อยเมื่อทำงานในบริบทต่อไดเรกทอรีเมื่อเทียบกับบริบทต่อเซิร์ฟเวอร์

คุณสามารถหลีกเลี่ยงปัญหานี้ได้โดยการเลือกทับเครื่องหมายทับล่วงหน้า นอกจากนี้คุณสามารถใช้ RedirectMatch ใน VirtualHost ที่ว่างเปล่าด้วยโดเมนส่วนเกินของคุณซึ่งสร้างการประมวลผลที่น้อยลงและสามารถดูสะอาดตาขึ้น

<VirtualHost *>
ServerName example.com
ServerAlias other.example.com
..
RedirectMatch permanent ^/?(.*) http://example.com/$1
</VirtualHost>


ดี ฉันชอบแนวทาง RedirectMatch ฉันอาจจะไปกับสิ่งนี้เพราะมันคือการเปลี่ยนเส้นทางที่ฉันต้องการจะบรรลุ
davekaro

1

ฉันรวมโพสต์นี้เพื่อความสมบูรณ์

เอกสาร Apacheอธิบายว่าทำไมปัญหานี้เกิดขึ้นเป็นอย่างดีและเป็นเหตุผลว่า 'RewriteBase' สั่งมีอยู่

เพียงรวมคำสั่ง 'RewriteBase' ในไฟล์. htaccess ของคุณควรจะได้ผลลัพธ์ที่ต้องการ

ตัวอย่าง:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

จากเอกสาร Apache 2.2 mod_rewrite:

คำสั่ง RewriteBase ตั้ง URL พื้นฐานสำหรับการเขียนซ้ำสำหรับแต่ละไดเรกทอรีอย่างชัดเจน

กฎง่ายๆของฉันคือการใช้ 'RewriteBase' ในไฟล์. htaccess เกือบทุกครั้งและไม่ใช้ใน Apache config


0

ฉันไม่มีเวลาจัดการกับปัญหานี้ดังนั้นเพียงแค่เขียน // เป็น / :)

RewriteCond %{THE_REQUEST} //
RewriteRule ^(.*)$ http://domain.com [R=301,L]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.