RewriteBase ทำงานใน. htaccess อย่างไร


227

ฉันได้เห็นสิ่งนี้ใน.htaccessตัวอย่างเล็ก ๆ น้อยๆ

RewriteBase /

ดูเหมือนว่าจะค่อนข้างคล้ายกับฟังก์ชันการทำงาน<base href="">ของ HTML

ฉันเชื่อว่ามันอาจเพิ่มมูลค่าของมันโดยอัตโนมัติไปยังจุดเริ่มต้นของRewriteRuleข้อความ (อาจเป็นไปได้โดยไม่มีเครื่องหมายทับ)

ฉันไม่สามารถทำงานได้อย่างถูกต้อง ฉันคิดว่าการใช้งานอาจมีประโยชน์มากสำหรับการพกพาไซต์เนื่องจากฉันมักจะมีเซิร์ฟเวอร์สำหรับการพัฒนาซึ่งแตกต่างจากเซิร์ฟเวอร์ที่ใช้งานจริง วิธีการปัจจุบันของฉันทำให้ฉันลบบางส่วนออกจากRewriteRuleงบของฉัน

ทุกคนสามารถอธิบายให้ฉันรู้วิธีนำไปใช้อย่างย่อได้หรือไม่

ขอบคุณ



RewriteBase ใช้งานได้เฉพาะในไดเรกทอรีหรือบริบท. htaccess ... อ้างถึงบริบทสำหรับลิงก์ @SalmanPK ที่ให้ไว้
Eddie B

1
ดูคำตอบนี้สำหรับคำอธิบายที่ดี stackoverflow.com/a/2137593/292060
goodeye

1
นี่คือคำตอบเชิงลึกเพิ่มเติม: stackoverflow.com/a/21348047/632951
Pacerier

นี่คือคำตอบแบบ 1 บรรทัด: stackoverflow.com/a/46541685/632951
Pacerier

คำตอบ:


102

ในคำพูดของฉันหลังจากอ่านเอกสารและทดลอง:

คุณสามารถใช้RewriteBaseเพื่อเป็นฐานสำหรับการเขียนใหม่ของคุณ พิจารณาสิ่งนี้

# invoke rewrite engine
    RewriteEngine On
    RewriteBase /~new/

# add trailing slash if missing
    rewriteRule ^(([a-z0-9\-]+/)*[a-z0-9\-]+)$ $1/ [NC,R=301,L]

นี่เป็นกฎจริงที่ฉันใช้เพื่อให้แน่ใจว่า URL มีเครื่องหมายสแลชต่อท้าย สิ่งนี้จะแปลง

http://www.example.com/~new/page

ถึง

http://www.example.com/~new/page/

โดยมีRewriteBaseมีคุณให้ทางญาติมาปิดRewriteBaseพารามิเตอร์


10
“ หลุดพารามิเตอร์ RewriteBase” - คุณหมายถึงพารามิเตอร์ rewriteRule หรือไม่ :)
Kissaki

1
ฉันต้องการให้ชัดเจนขึ้นรายละเอียดบางอย่างเกี่ยวกับ htaccess .. ที่ไม่ ReWriteBase ตั้งค่าสำหรับกฎทั้งหมดใน htaccess ต่อไปนี้การประกาศสิ่งที่? มีวิธียกเลิกการตั้งค่าหรือไม่สามารถรีเซ็ตได้หรือไม่
เดมอน

3
@Kissaki: ไม่$1ตรงกับรูปแบบ RewriteRule ในวงเล็บ แต่พา ธ สัมพัทธ์สำหรับการแทนที่จะปิดพารามิเตอร์ RewriteBase /~new/$1/ดังนั้นการเปลี่ยนตัวผู้เล่นที่เกิดคือ
MrWhite

3
@Damon: ดูคำถามนี้เกี่ยวกับRewriteBaseคำสั่งหลายคำ ในระยะสั้นคุณไม่สามารถมีมากกว่าหนึ่ง - ฉันคิดว่าคำสั่งสุดท้าย RewriteBaseชนะและส่งผลกระทบต่อไฟล์. htaccess ทั้งหมด
MrWhite

24
-1; คำตอบนี้ดูเหมือนว่าจะช่วยคนอื่น ๆ แต่ฉันเป็นคนทึบแสงทั้งหมด ฉันเดาได้ว่า"คุณสามารถใช้RewriteBaseเป็นฐานสำหรับการเขียนใหม่ของคุณ" - นั่นเป็นเพียงการจัดเรียงคำใหม่ - แต่ฉันไม่รู้ว่า "ฐาน" อยู่ในบริบทนี้อย่างไรและความหมายของ ตัวอย่างที่คุณระบุจะแตกต่างกันหากRewriteBaseลบบรรทัดนั้น ออกไปด้วยตนเองฉันไป ...
Mark Amery

89

RewriteBaseใช้กับเป้าหมายของกฎการเขียนซ้ำแบบสัมพันธ์เท่านั้น

  • ใช้ RewriteBase เช่นนี้ ...

    RewriteBase /folder/
    RewriteRule a\.html b.html
    
  • โดยพื้นฐานแล้วเหมือนกับ ...

    RewriteRule a\.html /folder/b.html
    
  • แต่เมื่อไฟล์. htaccess อยู่ด้านใน/folder/นี่จะชี้ไปยังเป้าหมายเดียวกัน:

    RewriteRule a\.html b.html
    

แม้ว่าเอกสารจะหมายถึงการใช้เสมอRewriteBaseแต่ Apache มักตรวจพบอย่างถูกต้องสำหรับเส้นทางภายใต้ DocumentRoot เว้นแต่:

  • คุณกำลังใช้Aliasคำสั่ง

  • คุณกำลังใช้. htaccess เขียนกฎใหม่เพื่อทำการเปลี่ยนเส้นทาง HTTP (แทนที่จะเขียนใหม่แบบเงียบ) ไปยังURL ที่เกี่ยวข้อง

ในกรณีเหล่านี้คุณอาจพบว่าคุณต้องระบุ RewriteBase

อย่างไรก็ตามเนื่องจากเป็นคำสั่งที่สับสนคุณควรระบุ URIs แบบสัมบูรณ์ (หรือที่เรียกว่า 'รูทญาติ') ในเป้าหมายที่เขียนซ้ำของคุณ นักพัฒนาอื่น ๆ ที่อ่านกฎของคุณจะเข้าใจสิ่งเหล่านี้ได้ง่ายขึ้น



อ้างจากคำตอบเชิงลึกที่ยอดเยี่ยมของจอนหลินที่นี่ :

ในไฟล์ htaccess mod_rewrite จะทำงานคล้ายกับ<Directory>หรือ<Location>คอนเทนเนอร์ และRewriteBaseใช้เพื่อจัดทำฐานพา ธ สัมพัทธ์

ตัวอย่างเช่นสมมติว่าคุณมีโครงสร้างโฟลเดอร์นี้:

DocumentRoot
|-- subdir1
`-- subdir2
    `-- subsubdir

ดังนั้นคุณสามารถเข้าถึง:

  • http://example.com/ (ราก)
  • http://example.com/subdir1 (subdir1)
  • http://example.com/subdir2 (subdir2)
  • http://example.com/subdir2/subsubdir (subsubdir)

URI ที่ส่งผ่าน a RewriteRuleนั้นสัมพันธ์กับไดเรกทอรีที่มีไฟล์ htaccess ดังนั้นถ้าคุณมี:

RewriteRule ^(.*)$ - 
  • ใน htaccess รากและขอเป็น/a/b/c/dแล้วจับ URI ( $1) a/b/c/dเป็น
  • หากกฎอยู่ในsubdir2และคำขอ/subdir2/e/f/gนั้นจะเป็น URI ที่จับe/f/gได้
  • หากการปกครองที่อยู่ในsubsubdirและขอเป็น/subdir2/subsubdir/x/y/zแล้วจับ URI x/y/zคือ

ไดเรกทอรีที่กฎนั้นมีอยู่นั้นส่วนนั้นถูกแยกออกจาก URI การเขียนซ้ำไม่มีผลกับสิ่งนี้นี่เป็นเพียงการทำงานของแต่ละไดเรกทอรี

สิ่งที่ฐานเขียนไม่ทำคือให้ฐาน URL เส้นทาง ( ไม่ฐานไฟล์เส้นทาง) สำหรับเส้นทางญาติใด ๆ ในเป้าหมายของกฎ สมมติว่าคุณมีกฎนี้:

RewriteRule ^foo$ bar.php [L]

bar.phpเป็นเส้นทางญาติเมื่อเทียบกับ:

RewriteRule ^foo$ /bar.php [L]

โดยที่/bar.phpเป็นเส้นทางที่แน่นอน เส้นทางแน่นอนจะเสมอเป็น "ราก" (ในโครงสร้างไดเรกทอรีข้างต้น) นั่นหมายความว่าไม่ว่ากฎนั้นจะอยู่ใน "root", "subdir1", "subsubdir" ฯลฯ/bar.phpเส้นทางจะจับคู่กับhttp://example.com/bar.phpเสมอ

แต่กฎอื่น ๆ ที่มีเส้นทางสัมพัทธ์มันขึ้นอยู่กับไดเรกทอรีที่กฎอยู่ค่ะดังนั้นถ้า

RewriteRule ^foo$ bar.php [L]

อยู่ใน "ราก" และคุณไปที่คุณได้รับบริการhttp://example.com/foo http://example.com/bar.phpแต่ถ้ากฎที่อยู่ใน "subdir1 directory" และคุณไปที่คุณได้รับบริการhttp://example.com/subdir1/foo http://example.com/subdir1/bar.phpฯลฯ บางครั้งวิธีนี้ใช้งานได้และบางครั้งไม่เป็นไปตามที่เอกสารระบุว่าควรใช้เส้นทางที่สัมพันธ์กัน แต่ส่วนใหญ่แล้วดูเหมือนว่าจะใช้งานได้ ยกเว้นเมื่อคุณเปลี่ยนเส้นทาง (ใช้การRตั้งค่าสถานะหรือโดยปริยายเพราะคุณhttp://hostอยู่ในเป้าหมายของกฎ) นั่นหมายถึงกฎนี้:

RewriteRule ^foo$ bar.php [L,R]

ถ้ามันใน "subdir2 directory" และคุณจะไปhttp://example.com/subdir2/foo, mod_rewrite จะผิดพลาดทางญาติเป็นไฟล์เส้นทางแทน URL เส้นทางและเนื่องจากธงคุณจะจบลงได้รับการเปลี่ยนเส้นทางไปยังสิ่งที่ต้องการ:R http://example.com/var/www/localhost/htdocs/subdir1ซึ่งเห็นได้ชัดว่าไม่ใช่สิ่งที่คุณต้องการ

นี่คือที่RewriteBaseมาคำสั่งบอก mod_rewrite สิ่งที่จะผนวกกับจุดเริ่มต้นของทุกเส้นทางญาติ ดังนั้นถ้าฉันมี:

RewriteBase /blah/
RewriteRule ^foo$ bar.php [L]

ใน "subsubdir" จะไปhttp://example.com/subdir2/subsubdir/fooรับใช้ฉันจริงhttp://example.com/blah/bar.phpๆ "bar.php" ถูกเพิ่มเข้าที่ท้ายฐาน ในทางปฏิบัติตัวอย่างนี้มักจะไม่ใช่สิ่งที่คุณต้องการเพราะคุณไม่สามารถมีหลายฐานในที่เก็บไดเรกทอรีเดียวกันหรือไฟล์ htaccess

ในกรณีส่วนใหญ่จะใช้แบบนี้:

RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]

โดยที่กฎเหล่านั้นจะอยู่ในไดเรกทอรี "subdir1" และ

RewriteBase /subdir2/subsubdir/
RewriteRule ^foo$ bar.php [L]

จะอยู่ในไดเรกทอรี "subsubdir"

ส่วนนี้ช่วยให้คุณสามารถทำให้กฎของคุณเป็นแบบพกพาได้ดังนั้นคุณสามารถวางกฎลงในไดเรกทอรีใดก็ได้และต้องการเปลี่ยนฐานแทนที่จะเป็นกฎจำนวนมาก ตัวอย่างเช่นถ้าคุณมี:

RewriteEngine On
RewriteRule ^foo$ /subdir1/bar.php [L]
RewriteRule ^blah1$ /subdir1/blah.php?id=1 [L]
RewriteRule ^blah2$ /subdir1/blah2.php [L]
...

เช่นที่http://example.com/subdir1/fooจะให้บริการhttp://example.com/subdir1/bar.phpฯลฯ และบอกว่าคุณตัดสินใจที่จะย้ายไฟล์และกฎเหล่านั้นทั้งหมดไปยังไดเรกทอรี "subsubdir" แทนที่จะเปลี่ยนทุกอินสแตนซ์/subdir1/เป็น/subdir2/subsubdir/คุณอาจมีเพียงฐาน:

RewriteEngine On
RewriteBase /subdir1/
RewriteRule ^foo$ bar.php [L]
RewriteRule ^blah1$ blah.php?id=1 [L]
RewriteRule ^blah2$ blah2.php [L]
...

และเมื่อคุณต้องการย้ายไฟล์เหล่านั้นและกฎไปยังไดเรกทอรีอื่นเพียงแค่เปลี่ยนฐาน:

RewriteBase /subdir2/subsubdir/

และนั่นคือมัน


RewriteEngine Onสำหรับฉันฉันพลาด ตัวอย่างเช่นไม่จำเป็นต้องใช้ 1 และ 1 แต่จำเป็นต้องใช้กับเซิร์ฟเวอร์เฉพาะของฉัน
Portekoi

41

AFAIK, RewriteBase ใช้เพื่อแก้ไขกรณีที่ mod_rewrite กำลังทำงานอยู่ใน.htaccessไฟล์ที่ไม่ได้อยู่ที่รูทของไซต์และมันจะเดาเส้นทางของเว็บที่ไม่ถูกต้อง (ตรงข้ามกับเส้นทางของระบบไฟล์) สำหรับโฟลเดอร์ที่มันทำงานอยู่ดังนั้น RewriteRule ใน. htaccess ในโฟลเดอร์ที่จับคู่กับhttp://example.com/myfolderคุณสามารถใช้:

RewriteBase myfolder

หาก mod_rewrite ทำงานไม่ถูกต้อง

พยายามที่จะใช้มันเพื่อให้ได้สิ่งที่ผิดปกติมากกว่าที่จะแก้ไขปัญหานี้ดูเหมือนสูตรที่จะสับสน


2
มันจำเป็นต้องจบด้วยเครื่องหมายทับหรือไม่?
Pacerier

@ ตนเอง, ไม่ผ่านการทดสอบและอธิบายย่อยได้ที่นี่: stackoverflow.com/a/11443194/632951
Pacerier

23

RewriteBase มีประโยชน์เฉพาะในสถานการณ์ที่คุณสามารถใส่. htaccess ไว้ที่รูทของเว็บไซต์ของคุณเท่านั้น มิฉะนั้นคุณอาจจะดีกว่าการวางไฟล์. htaccess ที่แตกต่างกันในไดเรกทอรีต่าง ๆ ในเว็บไซต์ของคุณและละเว้นคำสั่ง RewriteBase อย่างสมบูรณ์

เมื่อเร็ว ๆ นี้สำหรับไซต์ที่ซับซ้อนฉันได้ทำการลบออกเพราะมันทำให้การปรับใช้ไฟล์จากการทดสอบเพื่อให้มีความซับซ้อนขึ้นอีกขั้น


22
แม้ว่านี่อาจเป็นคำแนะนำที่ดี แต่นี่ไม่ใช่คำตอบสำหรับคำถามทั้งหมด มันควรจะได้รับการแสดงความคิดเห็นคำถามไม่ได้รับ upvotes (มาก) และไม่แน่นอนยอมรับว่าเป็น "คำตอบ"
Kissaki

3
"ดีกว่าการวางไฟล์. htaccess ที่แตกต่างกันในไดเรกทอรีต่าง ๆ " - ฉันไม่แน่ใจว่านี่เป็นคำแนะนำที่ดีใช่ไหม การมีไฟล์. htaccess ประอยู่ทั่วไซต์ของคุณสามารถทำให้การดีบัก / บำรุงรักษาเป็นฝันร้ายได้ ฉันจะบอกว่าเป็นการดีกว่าที่จะมีไฟล์. htaccess หนึ่งไฟล์ในรูทของเว็บไซต์ของคุณ
MrWhite

1
@ w3d นอกจากนี้ยังมีช่วงเวลาสำคัญ: ทุกครั้งที่มีการเข้าถึงไดเรกทอรีย่อยไฟล์. htaccess หลายไฟล์จะถูกแยกวิเคราะห์ (จากรากถึงไดเรกทอรีย่อยปัจจุบัน) มีไฟล์จำนวนมากสามารถลดความเร็วของคำตอบโดยรวมที่จะร้องขอเมื่อเทียบกับไฟล์เดียวในรากถึงแม้ว่ามันจะมีจำนวนมากของกฎ ..
Erenor ลาปาซ

19

เมื่อฉันพัฒนามันอยู่ในโดเมนอื่นภายในโฟลเดอร์ เมื่อฉันใช้เว็บไซต์สดโฟลเดอร์นั้นจะไม่มีอีกต่อไป การใช้ RewriteBase ทำให้ฉันสามารถใช้ไฟล์. htaccess เดียวกันในทั้งสองสภาพแวดล้อมได้

เมื่ออยู่:

RewriteBase /
# RewriteBase /dev_folder/

เมื่อพัฒนา:

# RewriteBase /
RewriteBase /dev_folder/

4
ฉันแน่ใจว่านี่จะไม่ทำงาน ถ้าคุณใช้%{REQUEST_URI}ในRewriteCondคำสั่งเช่น?
MrWhite

1
@ user1669830 หากคุณมี rewriterule เพียงครั้งเดียวคุณสามารถเพิ่มฐานไปยัง rewriterule stackoverflow.com/a/46541685/632951
Pacerier

18

คำอธิบายที่ชัดเจนผมพบว่าไม่ได้อยู่ในปัจจุบัน 2.4 เอกสาร Apache แต่ในรุ่น 2.0

#  /abc/def/.htaccess -- per-dir config file for directory /abc/def
#  Remember: /abc/def is the physical path of /xyz, i.e., the server
#            has a 'Alias /xyz /abc/def' directive e.g.

RewriteEngine On

#  let the server know that we were reached via /xyz and not
#  via the physical path prefix /abc/def
RewriteBase   /xyz

มันทำงานยังไง? สำหรับคุณ apache แฮกเกอร์เอกสาร 2.0 นี้จะให้ "ข้อมูลรายละเอียดเกี่ยวกับขั้นตอนการประมวลผลภายใน"

เรียนรู้บทเรียน: ในขณะที่เราต้องคุ้นเคยกับ "ปัจจุบัน" อัญมณีสามารถพบได้ในบันทึก


3

คำสั่งนี้สามารถตั้งค่า URL พื้นฐานสำหรับการเขียนของคุณใหม่ได้อย่างชัดเจน หากคุณต้องการเริ่มต้นในรูทโดเมนของคุณคุณจะต้องรวมบรรทัดต่อไปนี้ก่อนที่ RewriteRule ของคุณ:

RewriteBase /

2

ฉันเชื่อว่าข้อความที่ตัดตอนมาจากเอกสาร Apache นี้ช่วยเติมเต็มคำตอบก่อนหน้าได้ดี:

จำเป็นต้องมีคำสั่งนี้เมื่อคุณใช้เส้นทางสัมพัทธ์ในการทดแทนในบริบทต่อไดเรกทอรี (htaccess) เว้นแต่ว่าเงื่อนไขใด ๆ ต่อไปนี้เป็นจริง:

  • คำขอต้นฉบับและการทดแทนอยู่ภายใต้ DocumentRoot (ตรงข้ามกับวิธีอื่นที่สามารถเข้าถึงได้เช่น Alias)

  • พา ธ ของระบบไฟล์ไปยังไดเรกทอรีที่มี RewriteRule ซึ่งต่อท้ายด้วยการแทนที่แบบสัมพัทธ์ก็ใช้ได้เช่นเดียวกับพา ธ URL บนเซิร์ฟเวอร์ (ซึ่งไม่ค่อยเกิดขึ้น)

ดังที่ได้กล่าวไว้ก่อนหน้านี้ในบริบทอื่น ๆ จะเป็นประโยชน์เฉพาะเพื่อทำให้กฎของคุณสั้นลง นอกจากนี้ตามที่กล่าวไว้ก่อนหน้านี้คุณสามารถบรรลุสิ่งเดียวกันโดยการวางไฟล์ htaccess ในไดเรกทอรีย่อย

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