ในการโฮสต์ Apache เก่า เรามี.htaccessไฟล์ต่อไปนี้อยู่ภายในpublic_html/adm:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /adm/index.php [L]
</IfModule>

สิ่งนี้ควรเปลี่ยนเส้นทางทุก url หลังจากadmsubdir ไปยัง/adm/index.phpไฟล์ หากไม่มีพาธ และทำงานได้ดี

จากนั้นฉันก็ย้ายเว็บไซต์นี้ไปที่ IIS (v8.5) และใช้เครื่องมือ "นำเข้ากฎ..." ฉันพยายามบรรลุผลเช่นเดียวกัน แต่ในตอนแรกมันยุ่งกับ URL อื่นที่ไม่ใช่ URL ที่อยู่ใต้/admเส้นทาง ในความพยายามที่จะเอาชนะสิ่งนี้ ฉันได้เปลี่ยน.htaccessไฟล์ต้นฉบับเล็กน้อย เช่นด้านล่าง:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond adm/%{REQUEST_FILENAME} !-f
RewriteCond adm/%{REQUEST_FILENAME} !-d
RewriteRule adm/. /adm/index.php [L]
</IfModule>

กฎ IIS ที่ได้จะเป็นดังนี้:

<rewrite>
    <rules>
        <rule name="Imported Rule 1" enabled="true" stopProcessing="true">
            <match url="adm/." ignoreCase="false" />
            <conditions logicalGrouping="MatchAll">
                <add input="adm/{REQUEST_FILENAME}" matchType="IsFile" pattern="" ignoreCase="true" negate="true" />
                <add input="adm/{REQUEST_FILENAME}" matchType="IsDirectory" pattern="" ignoreCase="true" negate="true" />
            </conditions>
            <action type="Rewrite" url="/adm/index.php" />
        </rule>
    </rules>
</rewrite>

ตอนแรกดูเหมือนว่าจะใช้งานได้(1) แต่ฉันสังเกตเห็นได้อย่างรวดเร็วว่าเส้นทางที่ถูกต้องกำลังถูกเปลี่ยนเส้นทางเช่นกัน(2) จะทำให้ทำงานได้อย่างถูกต้องได้อย่างไร?

  1. http://example.com/aaaaส่งคืนข้อผิดพลาด 404 และhttp://example.com/adm/aaaaส่งคืนเนื้อหาของhttp://example.com/adm/index.php(ซึ่งเป็นสิ่งที่คาดหวัง)

  2. http://example.com/adm/images/logo.pngซึ่งเป็นเส้นทางที่ถูกต้อง ส่งคืนเนื้อหาของไฟล์ index.php (ซึ่งถือเป็นความผิดพลาด)

นี่คือผลลัพธ์ของกฎการเขียนซ้ำจากweb.configไฟล์ มุมมองของ ii กฎการเขียนใหม่

ขอบคุณ.

answer

regex ของคุณไม่ถูกต้อง ไม่ตรงกับค่าทั้งหมดหลังจาก/

ผลลัพธ์ของ ผลตอบแทน ที่adm/.ตรงกันสำหรับ adm/iดังนั้นจึงถูกต้องที่สมมติว่าไม่มีไฟล์อยู่

คุณ regex ควรเป็น:adm/.*

เมื่อสร้างกฎใน IIS GUI ให้กดTest Patternปุ่มในMatch URLส่วนเพื่อดูผลลัพธ์

ไม่ตรงตามเงื่อนไขการแข่งขัน นี่เป็นเพราะการเพิ่ม (ผิดพลาด) adm/ต่อหน้าพวกเขา

ค่าของREQUEST_FILENAME ตัวแปรเซิร์ฟเวอร์คือพาธแบบเต็มบนระบบไฟล์ของไฟล์ (หรือไดเร็กทอรี) ที่ร้องขอ ในกรณีทดสอบเฉพาะของฉัน:

URL คำขอ: http://example.com/adm/images/logo.png
{REQUEST_FILENAME} :F:\IIS\example.com\adm\assets\img\logo.png

ด้วยเหตุผลที่ชัดเจน การต่อท้ายadm/ค่านั้นจะทำให้เป็นพาธระบบไฟล์ที่ไม่ถูกต้อง และด้วยเหตุนี้ กฎการเขียนซ้ำจะถูกบังคับใช้แม้กระทั่งกับไฟล์/ไดเร็กทอรีที่ถูกต้อง วิธีแก้ปัญหานั้นง่าย:

แก้ไขกฎการเขียนใหม่

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

ไวยากรณ์ regex ใหม่

อัปเดตกฎสำหรับweb.configไฟล์ดังนี้

<rewrite>
    <rules>
        <rule name="Imported Rule 1" enabled="true" stopProcessing="true">
            <match url="(adm\/).*" ignoreCase="false" />
            <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" pattern="" ignoreCase="true" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" pattern="" ignoreCase="true" negate="true" />
            </conditions>
            <action type="Rewrite" url="/adm/index.php" />
        </rule>
    </rules>
</rewrite>