เคล็ดลับสำหรับการดีบัก. htaccess เขียนกฎใหม่


272

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

ดังนั้น Q ของฉันที่นี่คือวิธีที่เราอยากจะแนะนำให้พวกเขาแก้ปัญหากฎของตัวเอง ฉันให้คำแนะนำด้านล่าง ข้อเสนอแนะอื่น ๆ จะได้รับการชื่นชม

  1. เข้าใจว่าเอ็นจิ้น mod_rewrite วนไปตาม.htaccessไฟล์ต่างๆ เครื่องยนต์รันลูปนี้:

    do
      execute server and vhost rewrites (in the Apache Virtual Host Config)
      find the lowest "Per Dir" .htaccess file on the file path with rewrites enabled
      if found(.htaccess)
         execute .htaccess rewrites (in the user's directory)
    while rewrite occurred
    

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

  2. ตรวจสอบให้แน่ใจว่าไวยากรณ์ของ Regexp แต่ละรายการนั้นถูกต้องโดยการทดสอบกับชุดรูปแบบการทดสอบเพื่อให้แน่ใจว่าเป็นไวยากรณ์ที่ถูกต้องและทำตามที่คุณต้องการพร้อมกับการทดสอบ URI ทั้งหมด ดูคำตอบด้านล่างสำหรับรายละเอียดเพิ่มเติม

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

  4. ใช้ต้นขั้วสคริปต์หุ่นการถ่ายโอนข้อมูลจากเซิร์ฟเวอร์และสิ่งแวดล้อมตัวแปร (ดูรายชื่อ 2 ) หากแอปของคุณใช้พูดblog/index.phpคุณสามารถคัดลอกสิ่งนี้ลงในtest/blog/index.phpและใช้เพื่อทดสอบกฎบล็อกของคุณในtestไดเรกทอรีย่อย คุณยังสามารถใช้ตัวแปรสภาพแวดล้อมเพื่อให้แน่ใจว่าเอ็นจินการเขียนใหม่ในการตีความสตริงการแทนที่อย่างถูกต้องเช่น

    RewriteRule ^(.*) - [E=TEST0:%{DOCUMENT_ROOT}/blog/html_cache/$1.html]
    

    และค้นหาตัวแปรREDIRECT_ *เหล่านี้ในการถ่ายโอนข้อมูล phpinfo BTW ฉันใช้สิ่งนี้และค้นพบในเว็บไซต์ของฉันที่ฉันต้องใช้%{ENV:DOCUMENT_ROOT_REAL}แทน ในกรณีของการเปลี่ยนเส้นทางวนลูป REDIRECT_REDIRECT_ *รายการรหัสผ่านก่อนหน้า ฯลฯ ..

  5. ตรวจสอบให้แน่ใจว่าคุณไม่ได้รับกัดโดยเบราว์เซอร์ของคุณไม่ถูกต้องแคช 301 เปลี่ยนเส้นทาง ดูคำตอบด้านล่าง ขอบคุณUlrich Palhaสำหรับเรื่องนี้

  6. เอ็นจินการเขียนซ้ำดูเหมือนว่ามีความไวต่อกฎที่เรียงซ้อนภายใน.htaccessบริบท (นั่นคือที่ที่RewriteRuleผลลัพธ์ในการทดแทนและสิ่งนี้ตกลงไปถึงกฎเพิ่มเติม) เนื่องจากฉันพบข้อบกพร่องที่มีคำขอย่อยภายใน(1)และการประมวลผลPATH_INFO ที่ไม่ถูกต้องได้รับการป้องกันโดยการใช้ธง [NS], [L] และ [PT]

มีข้อคิดเห็นหรือข้อเสนอแนะเพิ่มเติมอีกหรือไม่

รายการ 1 - phpinfo

<?php phpinfo(INFO_ENVIRONMENT|INFO_VARIABLES);

10
นี่เป็นสิ่งที่ดี ... บางทีคุณควรย้ายพวกเขาจากคำถามไปเป็นคำตอบ
w00t

@ w00t ฉันแยกตัวตรวจสอบ regexp ตามคำแนะนำของคุณเพราะฉันต้องการอ้างอิงโดยลิงก์ในคำตอบอื่น ๆ
TerryE

3
คุณอาจต้องการเพิ่มแผนภาพลำดับการควบคุมจากเอกสารไปยังคำแนะนำแรกของคุณ IMO ง่ายต่อการเข้าใจมากกว่ารหัสเทียมหรือคำอธิบายใด ๆ และนี่เป็นส่วนที่มืดที่สุดของวูดู mod-rewrite
SAT

หมายเลข 6 เป็นเรื่องใหญ่ กฎการเขียนซ้ำที่ทำงานแตกต่างกันในไฟล์กำหนดค่า apache มาตรฐานเทียบกับในไฟล์. htaccess จะต้องมีผู้คนจำนวนมากออกมา
เลนคอลลินส์

สิ่งที่อาจเพิ่มมูลค่าให้กับคำแนะนำเหล่านี้: ฉันใช้เวลาสักครู่ในการดีบักปัญหาด้วยการเปลี่ยนเส้นทางและไม่เขียนใหม่ ปรากฎว่าฉันเขียนใหม่เป็น "/ ความคิดเห็น" เมื่อฉันต้องการ "/ ความคิดเห็น /" มันเขียนใหม่เพื่อ "/ ความคิดเห็น" จากนั้นเซิร์ฟเวอร์ก็ทำการเปลี่ยนเส้นทางไปที่ "/ ความคิดเห็น /" พฤติกรรมที่ชัดเจนกับผู้ที่เคยใช้ Apache แต่อาจน้อยกว่าสำหรับ noobs อย่างฉัน
Chris

คำตอบ:


132

นี่คือเคล็ดลับเพิ่มเติมเล็กน้อยเกี่ยวกับกฎการทดสอบที่อาจช่วยให้การดีบักสำหรับผู้ใช้บนโฮสติ้งที่ใช้ร่วมกันง่ายขึ้น

1. ใช้ตัวแทนผู้ใช้ปลอม

เมื่อทดสอบกฎใหม่เพิ่มเงื่อนไขเพื่อดำเนินการกับfakeตัวแทนผู้ใช้ที่คุณจะใช้สำหรับคำขอของคุณเท่านั้น วิธีนี้จะไม่ส่งผลกระทบต่อบุคคลอื่นในไซต์ของคุณ

เช่น

#protect with a fake user agent
RewriteCond %{HTTP_USER_AGENT}  ^my-fake-user-agent$
#Here is the actual rule I am testing
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC] 
RewriteRule ^ http://www.domain.com%{REQUEST_URI} [L,R=302] 

หากคุณใช้ Firefox คุณสามารถใช้User Agent Switcherเพื่อสร้างสตริงตัวแทนผู้ใช้ปลอมและทดสอบ

2. อย่าใช้ 301 จนกว่าคุณจะทำการทดสอบเสร็จ

ฉันได้เห็นโพสต์มากมายที่ผู้คนยังคงทดสอบกฎของพวกเขาและพวกเขาใช้ 301 ของ ไม่ต้อง

หากคุณไม่ได้ใช้ข้อเสนอแนะ 1 ในเว็บไซต์ของคุณไม่เพียง แต่คุณ แต่ใครก็ตามที่เยี่ยมชมเว็บไซต์ของคุณในเวลานั้นจะได้รับผลกระทบจาก 301

โปรดจำไว้ว่าเบราว์เซอร์ของคุณถาวรและแคชถาวร ใช้ 302 แทนจนกว่าคุณจะแน่ใจแล้วเปลี่ยนเป็น 301

3. โปรดจำไว้ว่า 301 ของจะถูกแคชในเบราว์เซอร์ของคุณอย่างจริงจัง

หากกฎของคุณใช้งานไม่ได้และดูเหมือนว่าถูกต้องสำหรับคุณและคุณไม่ได้ใช้คำแนะนำ 1 และ 2 ให้ทำการทดสอบอีกครั้งหลังจากล้างแคชเบราว์เซอร์ของคุณหรือในขณะที่เรียกดูแบบส่วนตัว

4. ใช้เครื่องมือ HTTP Capture

ใช้เครื่องมือจับภาพ HTTP เช่นFiddlerเพื่อดูทราฟฟิก HTTP ที่แท้จริงระหว่างเบราว์เซอร์ของคุณและเซิร์ฟเวอร์

ในขณะที่คนอื่นอาจบอกว่าคุณsite does not look rightคุณสามารถดูและรายงานสิ่งนั้นall of the images, css and js are returning 404 errorsๆ ได้อย่างรวดเร็วและแคบลงปัญหา

ในขณะที่คนอื่น ๆ จะรายงานที่คุณคุณจะสามารถที่จะเห็นว่าพวกเขาเริ่มต้นที่started at URL A and ended at URL C URL A, were 302 redirected to URL B and 301 redirected to URL Cแม้ว่า URL C เป็นเป้าหมายสูงสุดคุณจะรู้ว่าสิ่งนี้ไม่ดีสำหรับ SEO และต้องได้รับการแก้ไข

คุณจะสามารถเห็นส่วนหัวของแคชที่ตั้งค่าไว้ที่ฝั่งเซิร์ฟเวอร์ร้องขอการเล่นซ้ำแก้ไขส่วนหัวคำขอเพื่อทดสอบ ...



9
Ulrich ขอบคุณมากสำหรับข้อมูลนี้ คุณเลือกบางแง่มุมที่ฉันไม่เคยคิดที่จะใส่ในรายการของฉัน ในปัญหาการดีบัก 301 ฉันใช้ Chrome ใน "Private Browsing" (AKA "โหมดโป๊") เนื่องจากจะทำให้ข้อมูลสถานะนี้ทิ้งเมื่อคุณปิดหน้าต่าง ฉันหวังว่าคุณจะไม่รังเกียจฉันไม่ได้ "ยอมรับ" สิ่งนี้เนื่องจากเป็นจุดสำคัญ แต่ไม่ใช่คำตอบที่ดีที่สุด ขอบคุณอีกครั้ง. :)
TerryE

1
เพื่อให้ชัดเจน (คุณมีอยู่ในรหัสของคุณ แต่ไม่ได้ตรวจพบ) แต่เพื่อให้แน่ใจว่าคุณใช้การเปลี่ยนเส้นทาง 302 ไม่ใช่ 301 คุณต้อง[L,R=302]
icc97

6
คุณไม่จำเป็นต้องระบุอย่างชัดเจน[L, R=302]เพียงแค่ทำ[L,R]ตามค่าเริ่มต้นคือ302
Rahil Wazir

2
@goodeye ให้ดูที่ช่องทำเครื่องหมาย "Chrome> การตั้งค่า> ทั่วไป> ปิดใช้งานแคชขณะที่ DevTools เปิดอยู่"
johnsnails

83

การทดสอบ. htaccess ออนไลน์เขียนใหม่

ฉันพบนี้ Googling สำหรับ RegEx ช่วยเหลือมันบันทึกฉันมากเวลาจากที่มีการอัปโหลดใหม่.htaccessไฟล์ทุกครั้งที่ฉันจะทำให้การปรับเปลี่ยนขนาดเล็ก

จากเว็บไซต์:

ทดสอบ htaccess

ในการทดสอบกฎการเขียน htaccess เพียงกรอก URL ที่คุณใช้กฎนี้วางเนื้อหาของ htaccess ของคุณในพื้นที่อินพุตขนาดใหญ่แล้วกดปุ่ม "ตรวจสอบตอนนี้"


6
ขอบคุณสำหรับตัวชี้ไปที่เครื่องมือนี้ซึ่งฉันพบวิธีที่ตรงที่สุดในการแก้ไขปัญหาของฉัน
BobHy

หากคุณมีสิทธิ์เข้าถึง sshs webspace ของคุณตัวเลือกอื่นคือเปลี่ยน. htaccess โดยตรงผ่านตัวแก้ไขบนเซิร์ฟเวอร์
sjas

คุณจะต้องเพิกเฉยต่อคำเตือน ssl b / c ใบรับรองไซต์กำลังมีปัญหา แต่เว็บไซต์ยังคงอยู่ที่นั่น นี่คือทางออกที่ดีที่สุดและง่ายที่สุด มันให้ข้อมูลเชิงลึกที่เหลือเชื่อเกี่ยวกับสิ่งที่ผิดและผลลัพธ์ในการแก้ไขปัญหา FAST
toddmo

ขอบคุณที่ชี้ไปที่เครื่องมือนี้ มันมีประโยชน์บางครั้งการดีบัก apta htaccess เองนั้นช่างยากเหลือเกิน ขอบคุณ ขอบคุณมาก
Benyamin Limanto

ดูเหมือนว่าลิงก์ที่อ้างอิงนั้นมีค่าบั๊กและไม่ได้ให้ผลลัพธ์ที่แน่นอนเสมอไป โปรดตรวจสอบ apache จริงเพื่อให้แน่ใจว่าแน่นอน
Parth

13

อย่าลืมว่าในไฟล์. htaccess เป็น URL ที่เกี่ยวข้องที่ตรงกัน

ในไฟล์. htaccess RewriteRule ต่อไปนี้จะไม่ตรงกัน:

RewriteRule ^/(.*)     /something/$s

4
ใช่สตริงที่ป้อนเข้าสู่กฎการเขียนซ้ำนั้นเกี่ยวข้องและนำมาใช้กับการนำ/หน้า แต่การลอกนี้ไม่ได้เกิดขึ้นสำหรับสตริงการจับคู่ที่รวมอยู่ในคำสั่งRewrite Cond
TerryE

8

ตรวจสอบให้แน่ใจว่าไวยากรณ์ของแต่ละ Regexp นั้นถูกต้อง

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

ดูregexpCheck.phpด้านล่างเพื่อดูสคริปต์ง่ายๆที่คุณสามารถเพิ่มไปยังไดเรกทอรีส่วนตัว / ทดสอบในเว็บไซต์ของคุณเพื่อช่วยคุณทำสิ่งนี้ ฉันเก็บสั้น ๆ นี้ไว้มากกว่าจะสวย เพิ่งผ่านสิ่งนี้ไปเป็นไฟล์regexpCheck.phpในไดเรกทอรีทดสอบเพื่อใช้ในเว็บไซต์ของคุณ สิ่งนี้จะช่วยคุณสร้าง regexp และทดสอบกับรายการกรณีทดสอบในขณะที่คุณทำ ฉันใช้ PHP PCRE engine ที่นี่ แต่เมื่อได้ดูแหล่ง Apache แล้วมันก็เหมือนกับที่ใช้ใน Apache มี HowTos และแบบฝึกหัดมากมายที่ให้แม่แบบและสามารถช่วยคุณสร้างทักษะ regexp ของคุณ

รายการ 1 - regexpCheck.php

<html><head><title>Regexp checker</title></head><body>
<?php 
    $a_pattern= isset($_POST['pattern']) ? $_POST['pattern'] : "";
    $a_ntests = isset($_POST['ntests']) ? $_POST['ntests'] : 1;
    $a_test   = isset($_POST['test']) ? $_POST['test'] : array();
    
    $res = array(); $maxM=-1; 
    foreach($a_test as $t ){
        $rtn = @preg_match('#'.$a_pattern.'#',$t,$m);
        if($rtn == 1){
            $maxM=max($maxM,count($m));
            $res[]=array_merge( array('matched'),  $m );
        } else {
            $res[]=array(($rtn === FALSE ? 'invalid' : 'non-matched'));
        }
    } 
?> <p>&nbsp; </p>
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME'];?>">
    <label for="pl">Regexp Pattern: </label>
    <input id="p" name="pattern" size="50" value="<?php echo htmlentities($a_pattern,ENT_QUOTES,"UTF-8");;?>" />
    <label for="n">&nbsp; &nbsp; Number of test vectors: </label>
    <input id="n" name="ntests"  size="3" value="<?php echo $a_ntests;?>"/>
    <input type="submit" name="go" value="OK"/><hr/><p>&nbsp;</p>
    <table><thead><tr><td><b>Test Vector</b></td><td>&nbsp; &nbsp; <b>Result</b></td>
<?php 
    for ( $i=0; $i<$maxM; $i++ ) echo "<td>&nbsp; &nbsp; <b>\$$i</b></td>";
    echo "</tr><tbody>\n";
    for( $i=0; $i<$a_ntests; $i++ ){
        echo '<tr><td>&nbsp;<input name="test[]" value="', 
            htmlentities($a_test[$i], ENT_QUOTES,"UTF-8"),'" /></td>';
        foreach ($res[$i] as $v) { echo '<td>&nbsp; &nbsp; ',htmlentities($v, ENT_QUOTES,"UTF-8"),'&nbsp; &nbsp; </td>';}
        echo "</tr>\n";
    }
?> </table></form></body></html>

1
หมายเหตุด่วน: import_request_variablesเลิกใช้แล้วใน PHP 5.3 และลบใน 5.4 extract($_GET)ควบคู่กับextract($_POST)สามารถทำหน้าที่เดียวกัน แต่ตัวแปรทั้งหมดจะต้องลบคำนำหน้าออกจากชื่อของพวกเขา ที่มา: php.net/manual/en/function.import-request-variables.php
Jeff Lambert

@watcher ขอบคุณ ฉันได้อัปเดตเวอร์ชันในเครื่องของฉันให้เป็น 5.4 เมื่อปีที่แล้ว แต่ลืมเปลี่ยนโพสต์นี้ เสร็จแล้ว
TerryE

โอ้แม้หลังจากแก้ไขแล้วก็ไม่สามารถรับผลลัพธ์ที่ดีได้เพียงแค่คัดลอกรหัสของคุณ ... แต่ด้วยซอฟแวร์ของ regex ฉันคิดว่าเครื่องมือของคุณล้าสมัยไปแล้ว ตรวจสอบเครื่องมือเจ๋ง ๆ เหล่านี้: regex101.comหรือrefiddle.comหรือregexr.com
ซอฟต์แวร์ hexerei

@hexereisoftware โพสต์นี้มีอายุ 3 ปีดังนั้นอาจมีปัญหาเล็กน้อยขึ้นอยู่กับรุ่น PHP ที่ใช้ในขณะนี้และรุ่น Apache อย่างไรก็ตามมีหลายสายพันธุ์ของ regexp แต่ละตัวที่มีความแตกต่างเล็กน้อย อย่างที่ฉันบอกว่ารหัส Apache ใช้เอ็นจิน PCRE ที่คล้ายกับเอ็นจิน PHP มาก ฉันไม่แน่ใจว่าสิ่งที่แตกต่างกับตัวแปร othe เช่น. Net ดังนั้นในขณะที่ข้อเสนอแนะของคุณในการใช้ทรัพยากรออนไลน์เป็นสิ่งที่ดีฉันจะติดกับหนึ่งที่สนับสนุน apache หรือ PHP ไวยากรณ์อย่างชัดเจน :-)
TerryE

Perl จะใกล้เคียงที่สุด แต่ php ใช้ไวยากรณ์เดียวกัน
ซอฟต์แวร์ hexerei

7

ตรวจสอบให้แน่ใจว่าคุณใช้เครื่องหมายเปอร์เซ็นต์หน้าตัวแปรไม่ใช่เครื่องหมายดอลลาร์

มัน%{HTTP_HOST}, ไม่ ${HTTP_HOST}จะไม่มีสิ่งใดใน error_log จะไม่มีข้อผิดพลาดเซิร์ฟเวอร์ภายใน regexp ของคุณยังคงถูกต้องกฎจะไม่ตรงกัน นี่เป็นเรื่องที่น่ากลัวมากถ้าคุณทำงานกับ django / genshi templates มากมายและมี${}การทดแทนตัวแปรในหน่วยความจำของกล้ามเนื้อ


1
ใช่ตัวแปรการแทนที่$เกี่ยวข้องกับรูปแบบ RewriteRule ล่าสุดและ %ที่เกี่ยวข้องกับรูปแบบ RewriteCond และรายการพิเศษล่าสุดเช่น% {env: XXX}
TerryE

7

หนึ่งชั่วโมงจากสองสามชั่วโมงที่ฉันเสียไป:

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

หลังจากที่ฉันแก้ไข. htaccess-problem แล้วฉันใช้เวลาสองชั่วโมงในการพยายามแก้ไขเพิ่มเติมอีกครั้งแม้ว่าฉันจะลืมสิทธิ์บางอย่างไปก็ตาม


ฉันใช้ webservice การแชร์โฮสติ้งร่วมกันสำหรับเว็บไซต์ส่วนตัวของฉัน แต่สิ่งที่ฉันทำคือการตั้งค่าการทดสอบ VM ซึ่งสะท้อนสิ่งนี้ในแง่ของ PHP / Apache config, โฮมไดเร็กตอรี่ ฯลฯ อย่างไรก็ตามเนื่องจาก VM นี้อยู่ภายใต้ ผู้ดูแลระบบฉันสามารถเปิดใช้งานการบันทึก.htaccessซ้ำเพื่อวินิจฉัยปัญหาที่ยากๆ
TerryE

6

ตั้งค่าตัวแปรสภาพแวดล้อมและใช้ส่วนหัวเพื่อรับ:

คุณสามารถสร้างตัวแปรสภาพแวดล้อมใหม่ด้วยบรรทัด RewriteRule ตามที่กล่าวไว้โดย OP:

RewriteRule ^(.*) - [E=TEST0:%{DOCUMENT_ROOT}/blog/html_cache/$1.html]

แต่ถ้าคุณไม่สามารถรับสคริปต์ฝั่งเซิร์ฟเวอร์ให้ทำงานคุณจะอ่านตัวแปรสภาพแวดล้อมนี้ได้อย่างไร ทางออกหนึ่งคือการตั้งค่าส่วนหัว:

Header set TEST_FOOBAR "%{REDIRECT_TEST0}e"

ค่ายอมรับตัวระบุรูปแบบรวมถึงตัว%{NAME}eระบุสำหรับตัวแปรสภาพแวดล้อม (อย่าลืมตัวพิมพ์เล็ก) บางครั้งคุณจะต้องเพิ่มREDIRECT_คำนำหน้า แต่ฉันไม่ได้ทำงานเมื่อเพิ่มคำนำหน้าและเมื่อมันไม่ได้


คุณได้รับข้อมูลเชิงลึกเพิ่มเติมเกี่ยวกับเวลาที่จะใช้หรือไม่ใช้REDIRECT_คำนำหน้า? นอกจากนี้ฉันเห็นคำศัพท์เกี่ยวกับคำนำหน้าในบริบทอื่น ๆ (htaccess) เช่นกัน แต่ก็ไม่เคยชัดเจนว่าสิ่งที่มีความหมาย หมายความว่าคุณต้องตั้งชื่อตัวแปรของคุณด้วยคำนำหน้าหรือเพิ่มคำนำหน้าให้กับตัวแปรที่ระบุชื่อของคุณเมื่อใช้คำสั่งบางอย่าง (แต่ไม่ใช่คำสั่งอื่น ๆ )? ตัวอย่างของคุณเป็นคนแรกที่แสดงทั้งคำจำกัดความ var และการใช้งาน var ดังนั้นจากนี้ฉันมีแนวโน้มที่จะคิดอย่างหลัง! เอกสารได้รับความช่วยเหลือเล็กน้อย - พวกเขาคิดว่าเรารู้มากเกินไปและให้การอ้างอิง / ลิงค์น้อยเกินไป
SherylHohman

5

หากคุณกำลังสร้างการเปลี่ยนเส้นทางให้ทดสอบด้วยcurlเพื่อหลีกเลี่ยงปัญหาการแคชเบราว์เซอร์ ใช้ -I เพื่อดึงข้อมูลส่วนหัว http เท่านั้น ใช้ -L เพื่อติดตามการเปลี่ยนเส้นทางทั้งหมด


3

ฉันพบคำถามนี้ในขณะที่พยายามแก้ไขปัญหา mod_rewrite ของฉันและแน่นอนมีคำแนะนำที่เป็นประโยชน์ แต่ในที่สุดสิ่งที่สำคัญที่สุดคือการทำให้แน่ใจว่าไวยากรณ์ของคุณถูกต้อง เนื่องจากปัญหาเกี่ยวกับไวยากรณ์ RE ของฉันเองการติดตั้งสคริปต์ regexpCheck.php จึงไม่ใช่ตัวเลือกที่ทำงานได้

แต่เนื่องจาก Apache ใช้ Perl-Compatible Regular Expressions (PCRE) s เครื่องมือใด ๆ ที่ช่วยในการเขียน PCREs จึงควรช่วย ฉันเคยใช้เครื่องมือของ RegexPlanet กับ Java และ Javascript REs ในอดีตและยินดีที่จะพบว่าพวกเขาสนับสนุน Perl เช่นกัน

เพียงพิมพ์นิพจน์ปกติของคุณและ URL ตัวอย่างหนึ่งตัวอย่างขึ้นไปและจะบอกคุณว่า regex ตรงกับ ("1" ในคอลัมน์ "~ =") และถ้ามีกลุ่มการจับคู่ใด ๆ (ตัวเลขใน "แยก" คอลัมน์จะสอดคล้องกับตัวเลขที่ Apache คาดหวังเช่น $ 1, $ 2 และอื่น ๆ ) สำหรับแต่ละ URL พวกเขาอ้างว่าการสนับสนุน PCRE นั้น "เป็นรุ่นเบต้า" แต่มันก็เป็นสิ่งที่ฉันต้องการในการแก้ปัญหาไวยากรณ์ของฉัน

http://www.regexplanet.com/advanced/perl/index.html

ฉันแค่เพิ่มความคิดเห็นในคำตอบที่มีอยู่ แต่ชื่อเสียงของฉันยังไม่อยู่ในระดับนั้น หวังว่านี่จะช่วยใครซักคน


เครื่องมือที่ดี แต่รูปแบบที่น่ากลัว ... ลองดูเครื่องมือสุดเจ๋งเหล่านี้: regex101.comหรือrefiddle.comหรือregexr.com
ซอฟต์แวร์ hexerei

3

เกี่ยวกับ 4. คุณยังต้องตรวจสอบให้แน่ใจว่า "dummy script stub" ของคุณเป็น URL เป้าหมายหลังจากทำการเขียนใหม่ทั้งหมดไม่เช่นนั้นคุณจะไม่เห็นอะไรเลย!

เคล็ดลับที่คล้ายกัน / เกี่ยวข้อง (ดูคำถามนี้ ) คือการแทรกกฎชั่วคราวเช่น:

RewriteRule (.*) /show.php?url=$1 [END]

ไหนshow.phpบางสคริปต์ที่ง่ายมากที่จะแสดงเพียงของ$_GETพารามิเตอร์ (คุณสามารถแสดงตัวแปรสภาพแวดล้อมเกินไปถ้าคุณต้องการ)

สิ่งนี้จะหยุดการเขียนใหม่ในจุดที่คุณแทรกลงใน ruleset แทนที่จะเป็นจุดพักในตัวดีบัก

หากคุณใช้ Apache <2.3.9 คุณจะต้องใช้[L]มากกว่า[END]และคุณอาจต้องเพิ่ม:

RewriteRule ^show.php$ - [L]

ที่ส่วนบนสุดของชุดกฎของคุณหาก URL /show.phpนั้นถูกเขียนใหม่


3

ความผิดพลาดบางอย่างที่ฉันสังเกตเห็นเกิดขึ้นเมื่อเขียน .htaccess

การใช้การ^(.*)$ทำซ้ำในหลายกฎการใช้^(.*)$ทำให้กฎอื่น ๆ ไร้อำนาจในกรณีส่วนใหญ่เนื่องจากตรงกับ URL ทั้งหมดใน Hit เดียว

ดังนั้นหากเราใช้กฎสำหรับ URL นี้sapmle/urlมันก็จะใช้ URL นี้เช่นsapmle/url/stringกัน


[L] ควรใช้การตั้งค่าสถานะเพื่อให้แน่ใจว่ากฎของเราได้ดำเนินการแล้ว


ควรรู้เกี่ยวกับ:

ความแตกต่างใน% n และ $ n

%nมีการจับคู่ระหว่าง%{RewriteCond}ส่วนและ$nมีการจับคู่ใน%{RewriteRule}ส่วน

การทำงานของ RewriteBase

คำสั่ง RewriteBase ระบุคำนำหน้า URL ที่จะใช้สำหรับไดเรกทอรีต่อ (htaccess) คำสั่ง RewriteRule ที่ใช้แทนเส้นทางสัมพัทธ์

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

คำขอต้นฉบับและการทดแทนอยู่ภายใต้ DocumentRoot (ตรงข้ามกับวิธีอื่นที่สามารถเข้าถึงได้เช่น Alias) เส้นทางระบบไฟล์ไปยังไดเรกทอรีที่มี RewriteRule ซึ่งต่อท้ายด้วยการแทนที่แบบสัมพัทธ์ยังใช้ได้เช่นเดียวกับพา ธ URL บนเซิร์ฟเวอร์ (ซึ่งไม่ค่อยเกิดขึ้น) ใน Apache HTTP Server 2.4.16 และใหม่กว่าคำสั่งนี้อาจถูกละเว้นเมื่อคำขอถูกแมปผ่าน Alias ​​หรือ mod_userdir


2

หากคุณวางแผนที่จะเขียนมากกว่าหนึ่งบรรทัดของกฎใน. htacesss
อย่าคิดว่าจะลองวิธีการแก้ปัญหาอย่างใดอย่างหนึ่งเพื่อแก้จุดบกพร่อง

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

มีหลายหลุมอยู่ในกฎการเขียนใหม่มันไม่ใช่เรื่องตรรกะเลย
คุณสามารถทำให้ Apache ติดตั้งและใช้งานได้ภายในสิบนาทีมันคือ 10MB ใบอนุญาตดี * NIX / WIN / MAC พร้อมแม้จะไม่ติดตั้งก็ตาม
ตรวจสอบบรรทัดส่วนหัวของเซิร์ฟเวอร์ของคุณและรับ Apache รุ่นเดียวกันจากที่เก็บถาวรถ้าเก่า OP ของฉันยังอยู่ใน 2.0; ไม่รองรับหลายสิ่ง


Papo, ฉันใช้เซิร์ฟเวอร์เฉพาะ, VPS ที่โฮสต์โดย ISP และ VM ส่วนตัวภายในโครงสร้างการพัฒนาของฉัน แต่ฉันยังคงใช้บริการโฮสต์ที่ใช้ร่วมกันสำหรับโดเมนสาธารณะและอีเมลของฉันเพียงเพราะมันสะดวกและประหยัดค่าใช้จ่ายในการใช้การจัดการเต็มรูปแบบ บริการเหล่านี้ วิธีนี้มีการกำหนดเป้าหมายจริง ๆ ที่ผู้ใช้บริการที่ใช้ร่วมกัน การกำหนดค่า VM ส่วนตัวเพื่อทำมิรเรอร์เซอร์วิสแบบแบ่งใช้นั้นทำได้ยาก ใช่ถ้าคุณสามารถใช้การทดสอบ VM ช่วย แต่ฉันยังคงใช้ "เทคนิค" เหล่านี้เป็นครั้งคราวในบริการที่ใช้ร่วมกันของฉัน
TerryE

1
ผมจะเห็นด้วยกับเรื่องนี้ถ้าคุณได้รับการกรอบเป็นข้อเสนอแนะทางเลือกสำหรับการแก้จุดบกพร่องmod_rewriteกฎ แต่การเปิดตัว "ไม่ได้คิดเกี่ยวกับมัน" เป็นคำแนะนำที่ไม่ดีเพียงสำหรับผู้ใช้บริการที่ใช้ร่วมกันขั้นพื้นฐานที่กำลังดิ้นรนจะเข้าใจว่าทำไมพวกเขาhtaccessไฟล์ศศภอ' ไม่ทำงานในแบบที่ควรจะเป็น
TerryE

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

สำหรับส่วนที่สองจะมี IF ข้อความของฉันไม่เคยเริ่มต้นด้วย 'ไม่ต้องคิดแม้แต่น้อย' ฉันเห็นแล้วข้อความนี้ดูรุนแรงไปหน่อย แต่จริงทั้งหมด โดยเฉพาะอย่างยิ่งสำหรับผู้ที่ยังใหม่กับเรื่องนี้และพยายามที่จะเข้าใจ คำแนะนำที่นี่อาจทำให้เข้าใจผิดพวกเขาเช่นฉันสิ่งที่ฉันต้องการก็คือ regex ที่มั่นคงมันไม่ง่ายอย่างที่คุณเห็นข้อที่ 6) PATH_INFO ทำให้ฉันเดือดร้อนมากและไม่ใช่ข้อผิดพลาดอย่างที่คุณพูด แต่เป็นคุณลักษณะ หากคุณไม่ต้องการให้เพิ่มอีกครั้งให้ใช้ [DPI] แต่เฉพาะถ้าคุณดูที่บันทึกคุณจะเห็นว่ามีการเพิ่มที่นั่น นั่นเป็นเหตุผลว่าทำไมมีมากกว่าหนึ่งบรรทัดและคุณดีกว่าการใช้บันทึก
papo

1
ขออภัย @papo แต่เหตุผลของฉันสำหรับการลงคะแนน -1 คือฉันคิดว่าสิ่งนี้ "ไม่แม้แต่คิดเกี่ยวกับมัน" เป็นคำแนะนำที่ไม่ดี IMO หากประเด็นของคุณคือ "อยู่เหนือความซับซ้อนบางอย่างคุณอาจพบว่าง่ายขึ้นในการติดตั้งบริการ Apache ในเครื่องเพื่อแก้ไขข้อบกพร่องของ.htaccessไฟล์" นี่คือความสมดุลที่มากขึ้น ใช่มันเป็นเรื่องง่ายที่จะตั้งค่าบริการ Apache ในท้องที่ แต่การให้บริการโฮสติ้งที่ใช้ร่วมกันของผู้ให้บริการมีความซับซ้อนและเกินความสามารถของผู้ใช้หลายคนที่เพิ่งใช้งาน Wordpress เพียงคลิกเดียว พูดและมีปัญหากับ.htaccessไฟล์ของพวกเขา
TerryE

1

ฉันจะออกจากที่นี่อาจมีรายละเอียดที่ชัดเจน แต่ให้ฉันตีหัวของฉันเป็นเวลาหลายชั่วโมง: ระวังการใช้%{REQUEST_URI}เพราะสิ่งที่@Krist van Besienพูดในคำตอบของเขาถูกต้องทั้งหมดแต่ไม่ได้สำหรับสตริง REQUEST_URIเพราะสิ่งนี้TestString/เริ่มต้นด้วย ดังนั้นดูแล:

RewriteCond %{REQUEST_URI} ^/assets/$  
                            ^
                            | check this pesky fella right here if missing

0

(คล้ายกับแนวคิด Doin) เพื่อแสดงสิ่งที่กำลังจับคู่ฉันใช้รหัสนี้

$keys = array_keys($_GET);
foreach($keys as $i=>$key){
    echo "$i => $key <br>";
}

บันทึกลงใน r.php บนเซิร์ฟเวอร์รูทจากนั้นทำการทดสอบใน. htaccess
ตัวอย่างเช่นฉันต้องการจับคู่ URL ที่ไม่ได้ขึ้นต้นด้วยคำนำหน้าภาษา

RewriteRule ^(?!(en|de)/)(.*)$ /r.php?$1&$2 [L] #$1&$2&...
RewriteRule ^(.*)$ /r.php?nomatch [L] #report nomatch and exit

1
เพียงแค่ใช้ phpinfo () stub ตามที่ฉันกล่าวถึงในจุดที่ 4 บน O / P ของฉันก็ทำสิ่งเดียวกัน มองหาQUERY_STRING
TerryE

0

ตามที่ระบุโดย @Castell ผู้ทดสอบออนไลน์ทำงานได้ดีในการทดสอบการเปลี่ยนเส้นทางแบบบุคคลต่อไฟล์. htaccess อย่างไรก็ตามสิ่งที่น่าสนใจคือapi ที่เปิดเผยซึ่งสามารถใช้ในการทดสอบรายการ URL โดยใช้ออบเจ็กต์ json อย่างไรก็ตามเพื่อให้มีประโยชน์มากขึ้นฉันได้เขียนไฟล์สคริปต์ bashขนาดเล็กซึ่งใช้curlและjqเพื่อส่งรายการ URL และแยกการตอบสนอง json ลงในเอาต์พุตที่จัดรูปแบบ CSV พร้อมกับหมายเลขบรรทัดและกฎที่จับคู่ในไฟล์ htaccess พร้อมกับ URL ที่เปลี่ยนเส้นทางทำให้ค่อนข้างสะดวกในการเปรียบเทียบรายการ URL ในสเปรดชีตและกำหนดว่ากฎใดไม่ทำงานอย่างรวดเร็ว


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