เหตุใด RewriteRule สำหรับ“ ^ // (. *)” (เริ่มต้นด้วยเครื่องหมายทับคู่) จึงไม่เปลี่ยนเส้นทางไปยังเครื่องหมายทับเดียว

Aug 17 2020

มีกฎการเขียนซ้ำนี้ในบริบท vHost แต่จะไม่เขียนคำขอที่ขึ้นต้นด้วย//.*(เครื่องหมายทับคู่) เพียงแค่ให้บริการจาก/.*(สแลชเดี่ยว) แทนที่จะตอบสนองด้วยการเปลี่ยนเส้นทางไปที่/.*

RewriteRule "^//(.*)" "/$1" [R=301,L]

ทำไมถึงไม่ทำงาน

คำตอบ

2 MrWhite Aug 18 2020 at 06:51
RewriteRule "^//(.*)" "/$1" [R=301,L]

สิ่งนี้จะไม่ตรงกันเนื่องจากเส้นทาง URL ที่RewriteRule รูปแบบตรงกันได้มีการลดสแลชหลายอินสแตนซ์ทั้งหมดเป็นสแลชเดียวแล้ว

ในการเปลี่ยนเส้นทางคำขอดังกล่าวคุณสามารถใช้ "คุณลักษณะ" นี้และเพียงแค่เปลี่ยนเส้นทาง "เป็นตัวมันเอง" และตรวจสอบกับTHE_REQUESTตัวแปรของเซิร์ฟเวอร์แทนเพื่อตรวจสอบว่ามีเครื่องหมายทับหลายตัวในคำขอเริ่มต้นหรือไม่ THE_REQUESTเป็นบรรทัดแรกของส่วนหัวของคำขอและมี URL คำขอดิบที่ยังไม่ได้ประมวลผล (ไม่รวมโปรโตคอลและชื่อโฮสต์ แต่รวมถึงสตริงการสืบค้น) ที่ส่งจากไคลเอ็นต์

ตัวอย่างเช่นหากต้องการเปลี่ยนเส้นทางอินสแตนซ์ทั้งหมดของเครื่องหมายทับเป็นสแลชเดียวตลอดเส้นทาง URL ไม่ใช่แค่ในตอนเริ่มต้นคุณสามารถทำสิ่งนี้ได้:

RewriteCond %{THE_REQUEST} \s[^?]*//
RewriteRule (.*) $1 [R=301,L]

regex \s[^?]*//ทำให้แน่ใจว่าเราไม่จับคู่เครื่องหมายทับหลายตัวในส่วนสตริงข้อความค้นหาของ URL (ซึ่งจะส่งผลให้เกิดการวนรอบการเปลี่ยนเส้นทาง)


จะRewriteCond %{THE_REQUEST} ^//อนุญาตให้เราใช้กฎการเขียนซ้ำกับเฉพาะกฎที่ขึ้นต้นด้วยเครื่องหมายทับคู่โดยไม่สนใจอินสแตนซ์อื่น ๆ ทั้งหมดของเครื่องหมายทับคู่?

ไม่มากTHE_REQUESTตัวแปรเซิร์ฟเวอร์มีบรรทัดแรกทั้งหมดของส่วนหัวคำขอ HTTP กล่าวอีกนัยหนึ่งสตริงของรูปแบบ:

GET /foo/bar.html HTTP/1.1

หรือGET //foo/bar.html HTTP/1.1หากมีเครื่องหมายทับสองครั้งที่จุดเริ่มต้นของเส้นทาง URL ดังนั้นคุณจะต้องใช้สิ่งนี้แทน:

RewriteCond %{THE_REQUEST} \s//[^/]
RewriteRule (.*) $1 [R=301,L]

... เพื่อจับวิธีการร้องขอทั้งหมด และโดยเฉพาะอย่างยิ่งเพียงแค่สแลชสองครั้งไม่ใช่สามทับ ฯลฯ ที่จุดเริ่มต้นของเส้นทาง URL เท่านั้น

\s//[^/]- นั่นคือช่องว่าง (หลังวิธีการร้องขอ ) ตามด้วยเครื่องหมายทับ 2 ตัวและสิ่งอื่นที่ไม่ใช่เครื่องหมายทับ (เช่นช่องว่างสำหรับรูทเอกสารหรือเส้นทาง URL อื่น ๆ )