ลำดับไวยากรณ์ mod_rewrite
mod_rewrite มีกฎการสั่งซื้อเฉพาะบางอย่างที่ส่งผลต่อการประมวลผล ก่อนที่จะทำสิ่งใดเสร็จสิ้นRewriteEngine On
จำเป็นต้องมีคำสั่งเนื่องจากจะเปิดการประมวลผล mod_rewrite สิ่งนี้ควรอยู่ก่อนคำสั่งการแก้ไขอื่น ๆ
RewriteCond
ก่อนหน้านี้RewriteRule
ทำให้กฎหนึ่งข้อขึ้นอยู่กับเงื่อนไข RewriteRules ต่อไปนี้จะถูกประมวลผลราวกับว่าพวกเขาไม่ได้อยู่ภายใต้เงื่อนไข
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
ในกรณีที่ง่าย ๆ นี้ถ้าผู้อ้างอิง HTTP มาจาก serverfault.com ให้เปลี่ยนเส้นทางคำขอบล็อกไปยังหน้าเซิร์ฟเวอร์พิเศษ (เราเป็นเพียงผู้นั้น) อย่างไรก็ตามหากบล็อกด้านบนมีบรรทัด RewriteRule พิเศษ:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg $/blog/$1.sf.jpg
ไฟล์. jpg ทั้งหมดจะไปที่หน้าเซิร์ฟเวอร์ผิดปกติไม่ใช่เฉพาะไฟล์ที่มีผู้อ้างอิงที่ระบุว่ามาจากที่นี่ นี่ไม่ชัดเจนว่าเจตนาของวิธีการเขียนกฎเหล่านี้ สามารถทำได้หลายกฎของ RewriteCond:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
แต่อาจจะทำได้ด้วยไวยากรณ์การแทนที่ที่ซับซ้อน
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
RewriteRule ที่ซับซ้อนมากขึ้นมีเงื่อนไขสำหรับการประมวลผล parenthetical ล่าสุด(html|jpg)
บอกให้ RewriteRule ตรงกันสำหรับอย่างใดอย่างหนึ่งhtml
หรือjpg
และเพื่อแสดงสตริงที่ตรงกันเป็น $ 2 ในสตริงที่เขียนใหม่ สิ่งนี้มีเหตุผลเหมือนกันกับบล็อกก่อนหน้านี้ที่มีคู่ RewriteCond / RewriteRule สองคู่มันแค่ทำสองบรรทัดแทนสี่บรรทัด
หลายสาย RewriteCond เป็น ANDed โดยนัยและสามารถ ORed อย่างชัดเจน ในการจัดการผู้อ้างอิงจากทั้ง ServerFault และ Super User (ชัดแจ้ง OR):
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [OR]
RewriteCond %{HTTP_REFERER} ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
วิธีแสดงหน้าอ้างอิง ServerFault ด้วยเบราว์เซอร์ Chrome (โดยนัยและ)
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
RewriteBase
ยังมีคำสั่งที่เฉพาะเจาะจงตามที่ระบุว่าRewriteRule
คำสั่งต่อไปนี้จัดการกับการประมวลผลอย่างไร มันมีประโยชน์มากในไฟล์. htaccess หากใช้ควรเป็นคำสั่งแรกภายใต้ "RewriteEngine on" ในไฟล์. htaccess ใช้ตัวอย่างนี้:
RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
สิ่งนี้กำลังบอก mod_rewrite ว่า URL นี้ซึ่งกำลังจัดการอยู่นั้นมาถึงโดยhttp://example.com/blog/แทนที่จะเป็นเส้นทางไดเรกทอรีทางกายภาพ (/ home / $ Username / public_html / blog) และปฏิบัติตาม ด้วยเหตุนี้จึงRewriteRule
ถือว่าการเริ่มสตริงเป็นหลัง "/ บล็อก" ใน URL นี่คือสิ่งเดียวกันที่เขียนสองวิธีที่ต่างกัน หนึ่งรายการกับ RewriteBase อีกรายการหนึ่งที่ไม่มี:
RewriteEngine On
##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg) $1.sf.$2
##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
ดังที่คุณเห็นRewriteBase
อนุญาตให้เขียนกฎใหม่เพื่อใช้ประโยชน์จากพา ธ ของเว็บไซต์ไปยังเนื้อหามากกว่าเว็บเซิร์ฟเวอร์ซึ่งสามารถทำให้พวกเขาเข้าใจได้ง่ายขึ้นสำหรับผู้ที่แก้ไขไฟล์ดังกล่าว นอกจากนี้ยังสามารถทำให้คำสั่งสั้นลงซึ่งมีเสน่ห์ดึงดูด
RewriteRule จับคู่ไวยากรณ์
RewriteRule เองมีไวยากรณ์ที่ซับซ้อนสำหรับสตริงที่ตรงกัน ฉันจะครอบคลุมธง (สิ่งที่ต้องการ [PT]) ในส่วนอื่น เนื่องจาก Sysadmins เรียนรู้จากตัวอย่างบ่อยกว่าการอ่านman-pageฉันจะยกตัวอย่างและอธิบายสิ่งที่พวกเขาทำ
RewriteRule ^/blog/(.*)$ /newblog/$1
.*
สร้างตรงกับอักขระตัวเดียว ( .
) ศูนย์หรือมากกว่าครั้ง ( *
) ล้อมรอบไว้ในวงเล็บบอกให้จัดเตรียมสตริงที่ถูกจับคู่เป็นตัวแปร $ 1
RewriteRule ^/blog/.*/(.*)$ /newblog/$1
ในกรณีนี้ตัวแรก * ไม่ได้อยู่ใน parens ดังนั้นจึงไม่ได้จัดไว้ให้กับสตริงที่เขียนใหม่ กฎนี้จะลบระดับไดเรกทอรีในบล็อกไซต์ใหม่ (/blog/2009/sample.html จะกลายเป็น /newblog/sample.html)
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$2
ในกรณีนี้นิพจน์วงเล็บแรกจะตั้งค่ากลุ่มการจับคู่ สิ่งนี้กลายเป็น $ 1 ซึ่งไม่จำเป็นและดังนั้นจึงไม่ได้ใช้ในสตริงที่เขียนใหม่
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$1/$2
ในกรณีนี้เราใช้ $ 1 ในสตริงที่เขียนใหม่
RewriteRule ^/blog/(20[0-9][0-9])/(.*)$ /newblog/$1/$2
กฎนี้ใช้ไวยากรณ์ที่วงเล็บพิเศษที่ระบุตัวอักษรช่วง [0-9] ตรงกับตัวเลข 0 ถึง 9 กฎเฉพาะนี้จะจัดการปีจาก 2000 ถึง 2099
RewriteRule ^/blog/(20[0-9]{2})/(.*)$ /newblog/$1/$2
สิ่งนี้ทำสิ่งเดียวกันกับกฎก่อนหน้า แต่ส่วน {2} บอกให้ตรงกับอักขระก่อนหน้า (นิพจน์วงเล็บเหลี่ยมในกรณีนี้) สองครั้ง
RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html /newblog/$1/$2.shtml
กรณีนี้จะจับคู่ตัวอักษรตัวพิมพ์เล็กใด ๆ ในนิพจน์การจับคู่ที่สองและทำเพื่ออักขระมากเท่าที่จะ การ\.
สร้างบอกให้รักษาจุดเป็นช่วงเวลาจริงไม่ใช่ตัวอักษรพิเศษที่อยู่ในตัวอย่างก่อนหน้า มันจะพังถ้าชื่อไฟล์มีเครื่องหมายขีดกลางอยู่
RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html /newblog/$1/$2.shtml
กับดักชื่อไฟล์ที่มีขีดกลาง อย่างไรก็ตามเนื่องจาก-
เป็นอักขระพิเศษในนิพจน์วงเล็บเหลี่ยมจึงต้องเป็นอักขระตัวแรกในนิพจน์
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
รุ่นนี้ดักจับชื่อไฟล์ใด ๆ ด้วยตัวอักษรตัวเลขหรือ-
ตัวอักษรในชื่อไฟล์ นี่คือวิธีที่คุณระบุชุดอักขระจำนวนมากในนิพจน์วงเล็บเหลี่ยม
ธง RewriteRule
แฟล็กบนกฎการเขียนซ้ำมีโฮสต์ของความหมายและ usecasesพิเศษ
RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html /newblog/$1/$2.shtml [L]
แฟล็กคือ[L]
ที่ส่วนท้ายของนิพจน์ด้านบน สามารถใช้หลายสถานะคั่นด้วยเครื่องหมายจุลภาค เอกสารที่เชื่อมโยงอธิบายแต่ละเอกสาร แต่ที่นี่เป็นเอกสารต่อไป:
L = ล่าสุด หยุดการประมวลผล RewriteRules เมื่อสิ่งนี้ตรงกัน คำสั่งซื้อนับ!
C = เชน ทำการประมวลผล RewriteRule ต่อไป หากกฎนี้ไม่ตรงกันกฎต่อไปจะไม่ถูกเรียกใช้ เพิ่มเติมเกี่ยวกับเรื่องนี้ในภายหลัง
E = ตั้งค่าตัวแปรสภาพแวดล้อม Apache มีตัวแปรสภาพแวดล้อมต่าง ๆ ที่อาจส่งผลต่อพฤติกรรมของเว็บเซิร์ฟเวอร์
F = ต้องห้าม ส่งคืนข้อผิดพลาด 403 ที่ต้องห้ามถ้ากฎนี้ตรงกัน
G = หายไป ส่งคืนข้อผิดพลาด 410-Gone หากกฎนี้ตรงกัน
H = ตัวจัดการ บังคับให้คำร้องขอถูกจัดการราวกับว่าเป็นชนิด MIME ที่ระบุ
N = ถัดไป บังคับให้กฎเริ่มต้นใหม่อีกครั้งและจับคู่อีกครั้ง ระวัง! ลูปสามารถส่งผลให้
NC = ไม่มีกรณี ช่วยให้jpg
เพื่อให้ตรงกับทั้ง jpg และ JPG
NE = ไม่มีทางหนีรอด ป้องกันการเขียนอักขระพิเศษ (.? # & etc) ลงในโค้ดเลขฐานสิบหก
NS = ไม่มีข้อความย่อย หากคุณใช้เซิร์ฟเวอร์รวมถึงสิ่งนี้จะป้องกันไม่ให้ตรงกับไฟล์ที่รวม
P = พร็อกซี บังคับใช้กฎที่จะจัดการโดย mod_proxy ให้เนื้อหาจากเซิร์ฟเวอร์อื่น ๆ อย่างโปร่งใสเนื่องจากเว็บเซิร์ฟเวอร์ของคุณดึงข้อมูลและให้บริการอีกครั้ง นี่คือการตั้งค่าสถานะที่เป็นอันตรายตามที่เขียนไม่ดีจะเปลี่ยนเว็บเซิร์ฟเวอร์ของคุณเป็นพร็อกซีเปิดและนั่นคือไม่ดี
PT = ผ่าน คำนึงถึงคำสั่ง Alias ในการจับคู่ RewriteRule
QSA = QSAppend เมื่อสตริงเดิมมีข้อความค้นหา ( http://example.com/thing?asp=foo) ผนวกสตริงเคียวรีดั้งเดิมต่อท้ายสตริงที่เขียนใหม่ ปกติมันจะถูกทิ้ง สำคัญสำหรับเนื้อหาแบบไดนามิก
R = เปลี่ยนเส้นทาง ระบุการเปลี่ยนเส้นทาง HTTP ไปยัง URL ที่ระบุ ยังสามารถระบุรหัสการเปลี่ยนเส้นทางที่แน่นอน [R = 303] คล้ายกันมากRedirectMatch
ซึ่งเร็วกว่าและควรใช้เมื่อเป็นไปได้
S = ข้าม ข้ามกฏนี้
T = ประเภท ระบุประเภท mime ของเนื้อหาที่ส่งคืน คล้ายกับAddType
คำสั่งมาก
คุณรู้ว่าฉันพูดว่าอย่างไรที่RewriteCond
ใช้กับกฎหนึ่งเดียวเท่านั้น? ทีนี้คุณก็สามารถทำได้โดยการผูกมัด
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html [C]
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
เนื่องจาก RewriteRule แรกมีแฟล็กเชนกฎการเขียนซ้ำที่สองจะดำเนินการเมื่อครั้งแรกที่ทำซึ่งก็คือเมื่อกฎ RewriteCond ก่อนหน้าถูกจับคู่ มีประโยชน์ถ้าการแสดงออกปกติของ Apache ทำให้สมองของคุณเจ็บปวด อย่างไรก็ตามวิธี all-in-one-line ที่ฉันชี้ไปในส่วนแรกนั้นเร็วกว่าจากมุมมองการปรับให้เหมาะสมที่สุด
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
สิ่งนี้สามารถทำให้ง่ายขึ้นผ่านธง:
RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html /newblog/$1/$2.shtml [NC]
นอกจากนี้ธงบางรายการยังใช้กับ RewriteCond โดยเฉพาะอย่างยิ่ง NoCase
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [NC]
จะตรงกับ "ServerFault.com"