ในบทความก่อนหน้านี้ เราได้พูดคุยเกี่ยวกับประเด็นหลักหลายประการของการเขียน URL ใหม่ ในบทความสุดท้ายของชุดนี้ เราจะพูดถึงรายละเอียดและคุณลักษณะของการเขียน URL ระดับต่างๆ
ตามทฤษฎีแล้ว การเขียนซ้ำ URL ระดับ IIS ที่เขียนด้วยภาษา C หรือ C++ จะมีประสิทธิภาพสูงกว่าการเขียนซ้ำ URL ระดับ ASP.NET ที่เขียนด้วยโค้ดที่ได้รับการจัดการ แต่ฉันคิดว่าความแตกต่างในด้านนี้ไม่มีนัยสำคัญในกรณีส่วนใหญ่ และแทบจะเป็นไปไม่ได้เลยที่การแสดงนี้จะกลายเป็นคอขวดของประสิทธิภาพ ดังนั้น โดยทั่วไประดับของการเขียน URL ซ้ำที่เลือกจึงไม่ได้ถูกกำหนดโดยข้อกำหนดด้านประสิทธิภาพของแอปพลิเคชันของคุณ แล้วควรใช้การเขียน URL ใหม่ระดับไหน? หลังจากใช้ URL Rewrite ในระดับต่างๆ แล้ว เราควรคำนึงถึงอะไรบ้าง? ฉันมาที่นี่เพื่อพูดคุยเกี่ยวกับมุมมองส่วนตัวของฉัน
แม้ว่าองค์ประกอบการเขียนซ้ำ URL ปัจจุบันจะสามารถตอบสนองแอพพลิเคชันส่วนใหญ่ในแง่ของฟังก์ชันการทำงานได้ แต่ในบางจุด เรายังคงต้องการฟังก์ชันพิเศษบางอย่าง ตัวอย่างเช่น การเขียน URL ใหม่ตามชื่อโดเมนไม่ใช่เรื่องง่ายที่จะทำสำเร็จด้วยคอมโพเนนต์การเขียนซ้ำ URL ปัจจุบัน ขณะนี้ ISAPI Rewrite เชิงพาณิชย์สามารถรองรับสิ่งนี้ได้ ขออภัย UrlRewriter.NET และ IIRF แบบโอเพ่นซอร์สมีฟังก์ชันไม่เพียงพอในเรื่องนี้ ทั้งหมดจะถูกจับคู่ตามเส้นทางของคำขอที่เกี่ยวข้องกับไซต์ และชื่อโดเมนที่ร้องขอไม่สามารถใช้เป็นเงื่อนไขการจับคู่ได้ สิ่งนี้ต้องการให้เราขยายองค์ประกอบการเขียน URL ใหม่ สำหรับนักพัฒนา .NET ส่วนใหญ่ โค้ดที่ได้รับการจัดการเป็นตัวเลือกแรกสำหรับการพัฒนา ในขณะนี้ อาจจำเป็นต้องเลือกคอมโพเนนต์การเขียนซ้ำ URL ระดับ ASP.NET อย่างไรก็ตาม คุณสามารถดูตัวอย่างส่วนขยายจำนวนมากได้บนอินเทอร์เน็ต ไม่ว่าจะเป็น UrlRewriter.NET ในระดับ ASP.NET หรือ IIRF ในระดับ IIS
แต่ในความเป็นจริงแล้ว หากเราต้องการบรรลุฟังก์ชันข้างต้น เราก็สามารถทำได้ในสองขั้นตอนเช่นกัน อันดับแรก เราใช้ IIRF สำหรับการเขียน URL ใหม่ในระดับ IIS จากนั้นจึงเขียน URL ใหม่เพิ่มเติมในระดับ ASP.NET ตัวอย่างเช่น หากตอนนี้เราต้องการเขียน " http://jeffz.domain.com/articles " ใหม่เป็น "/ArticleList.aspx?owner=jeffz" ก่อนอื่นเราสามารถให้ IIRF ทำการเขียน URL ครั้งแรกใหม่โดยมีวัตถุประสงค์ในการเขียนใหม่ " /articles" ถูกเขียนใหม่เป็น "/ArticleList.aspx"
RewriteRule ^/Articles$ /ArticleList.aspx [I, L, U]
ด้วยวิธีนี้ โปรแกรม ASP.NET จะได้รับการร้องขอสำหรับ /ArticleList.aspx โดยตรง จากนั้นภายใน ASP.NET เราสามารถเขียน URL ครั้งที่สองได้ (เพื่อความสะดวกฉันยังคงเขียนใน Global.asax และแนะนำให้ใช้ HttpModule เพิ่มเติมในโปรเจ็กต์)
ป้องกัน โมฆะ Application_BeginRequest (ผู้ส่ง วัตถุ EventArgs e)
-
บริบท HttpContext = HttpContext .ปัจจุบัน;
โฮสต์ สตริง = context.Request.Url.Host;
เจ้าของ สตริง = host.Substring(0, host.IndexOf( '.' ));
context.RewritePath(context.Request.RawUrl + "?owner=" + เจ้าของ);
}
หลังจากเขียน URL ใหม่สองครั้ง ผลลัพธ์ที่เราต้องการก็บรรลุผล (ในโครงการจริง โค้ดด้านบนไม่สามารถนำมาใช้โดยตรงได้ เนื่องจากจำเป็นต้องตัดสินว่ามีสตริงการสืบค้นหรือไม่ ฯลฯ)
นอกจากนี้ การเขียนซ้ำ URL ระดับ ASP.NET สามารถทำงานได้เฉพาะใน ASP.NET เท่านั้น (สิ่งที่เห็นได้ชัด) หากคุณต้องการให้การเขียน URL ใหม่รองรับเทคโนโลยีเซิร์ฟเวอร์อื่นๆ เช่น PHP, RoR เป็นต้น คุณสามารถใช้การเขียนซ้ำ URL ระดับ IIS เท่านั้น (หรือฟังก์ชันการเขียน URL อื่น ๆ ที่ให้บริการโดยเทคโนโลยีเซิร์ฟเวอร์)
อักขระพิเศษบางตัวไม่ได้รับอนุญาตให้ปรากฏใน URL หรือเมื่อปรากฏใน URL ความหมายของคำขอจะเปลี่ยนไป ตัวอย่างเช่น เราจำเป็นต้องเขียน URL ใหม่บนหน้าการค้นหา เขียนใหม่ "/Search/xxx" เป็น "/Search.aspx?xxx" จากนั้นรับคำสำคัญที่ผู้ใช้ระบุโดยอิงตามสตริงหลังเครื่องหมายคำถาม หากใช้ UrlRewriter.NET เราจะใช้การกำหนดค่าต่อไปนี้:
< rewriter >
< เขียนใหม่ url = " ^/ค้นหา/(.+)$ " ถึง = " ~/Search.aspx?$1 " การประมวลผล = " หยุด " />
</ เขียนใหม่ >
ภายใต้สถานการณ์ปกติ การเขียน URL ใหม่นี้จะทำงานได้ตามปกติ แต่ถ้าผู้ใช้ใช้ "%" เป็นคำสำคัญ สถานการณ์จะแตกต่างออกไป เนื่องจากเราจะได้รับพร้อมท์หน้าข้อผิดพลาดต่อไปนี้:
เนื่องจากไม่อนุญาตให้ใช้ "%" ใน URL คุณสามารถไปที่เว็บไซต์ต่างๆ และลองขอเส้นทางบางอย่าง เช่น "ABC%25DEF" ("%25" ตามด้วย "%") และส่วนใหญ่จะพบข้อผิดพลาด "400 Bad Request" อย่างไรก็ตาม การใส่ "%" ในสตริงการสืบค้นถือเป็นเรื่องถูกกฎหมาย ใช่แล้ว เราไม่ได้เขียนคีย์เวิร์ดใหม่ลงในสตริงการสืบค้นใช่หรือไม่ ทำไมมันยังไม่ทำงาน? นอกจากนี้ยังกำหนดโดยวิธีดำเนินการ ASP.NET
คำขอที่ไม่ถูกต้องจะถูกกำหนดในขั้นตอนที่ 3 ของรูปด้านบน นั่นคือในขณะที่ยังอยู่ระหว่างการเริ่มต้น การเขียน URL ของเราใหม่เกิดขึ้นในเหตุการณ์ BeginRequest ในขั้นตอนที่ 4 เท่านั้น เมื่อคำขอมีอักขระที่ผิดกฎหมาย เราไม่มีโอกาสที่จะดำเนินการเขียน URL ใหม่เลย
แล้วเราจะจัดการกับปัญหานี้อย่างไร? ภายใต้สถานการณ์ปกติ มันจะไม่เป็นปัญหาใหญ่หากเราลบ % บนไคลเอนต์ (บางไซต์ทำเช่นนี้) แต่จะเป็นอย่างไรหากเราต้องเก็บไว้? จากนั้นใช้ Query String เพื่อส่งพารามิเตอร์ หรือเรายังสามารถใช้การเขียน URL ระดับ IIS ได้อีกด้วย ยังคงใช้ IIRF เป็นตัวอย่าง:
RewriteRule ^/Search/(.+)$ /Search.aspx?$1 [I, L, U]
เมื่อคำขอถูกส่งไปยัง IIS (ขั้นตอนที่ 1) และหลังจากเลือก ISAPI ที่ควรส่งแล้ว เกินกว่าสำหรับการดำเนินการ (ขั้นตอนที่ 2) การเขียน URL ใหม่เกิดขึ้นก่อนหน้านี้ หลังจากเขียน URL ใหม่แล้ว "%" ในที่อยู่จะถูกโอนไปยังสตริงการสืบค้น และเป็นเรื่องปกติตามกฎหมายเมื่อส่งมอบให้กับ ASP.NET เพื่อประมวลผล
สุดท้ายนี้ เรามาหารือเกี่ยวกับการกำหนดค่าหน้าข้อผิดพลาดกัน ตัวอย่างเช่น โดยทั่วไป เราจะกำหนดค่าหน้าแสดงข้อผิดพลาด 404 สำหรับแอปพลิเคชัน เพื่อว่าเมื่อผู้ใช้เข้าถึงทรัพยากรที่ไม่มีอยู่จริง เราก็สามารถแสดงหน้าเฉพาะเจาะจงแทนข้อความแจ้งข้อผิดพลาดเริ่มต้นได้ แต่ ณ จุดนี้ จะต้องกำหนดค่าการเขียน URL ในระดับที่แตกต่างกันโดยใช้วิธีการที่แตกต่างกัน
หากเราใช้การเขียน URL ระดับ ASP.NET โดยทั่วไปเราได้ตั้งค่า Wildcard Mapping ใน IIS เพื่อให้คำขอใดๆ (รวมถึง html, jpg ฯลฯ) จะถูกประมวลผลโดย ASP.NET หากมีการร้องขอทรัพยากรที่ไม่มีอยู่ ASP.NET จะออกข้อผิดพลาด 404 ดังนั้นควรกำหนดค่าหน้าข้อผิดพลาด 404 ใน web.config:
< customErrors โหมด = " เปิด " defaultRedirect = " GenericErrorPage.htm " >
< ข้อผิดพลาด รหัสสถานะ = " 404 " เปลี่ยนเส้นทาง = " FileNotFound.htm " />
</ customErrors >
หากเราใช้การเขียน Url Rewrite ระดับ IIS เราจะไม่กำหนดค่า Wildcard Mapping กล่าวอีกนัยหนึ่ง กลไก ASP.NET จะเริ่มทำงานเมื่อที่อยู่หลังจากเขียนใหม่เป็น aspx เท่านั้น (หรือสิ่งอื่น ๆ ที่ ASP.NET ISAPI ควรได้รับการจัดการ) หากผู้ใช้ร้องขอทรัพยากรที่ไม่มีอยู่ IIS จะออกข้อผิดพลาด 404 ในขณะนี้ หน้าข้อผิดพลาด 404 ควรได้รับการกำหนดค่าใน IIS:
จนถึงขณะนี้ได้มีการพูดคุยถึงหัวข้อการเขียน URL ใหม่แล้ว ในการพัฒนาจริง คุณจะต้องพบกับสถานการณ์ต่างๆ มากมาย แต่ตราบใดที่คุณเข้าใจกุญแจสำคัญของวิธีการเขียน URL ใหม่ และคิดตามวิธีการทำงานของโปรแกรม ผมเชื่อว่าโดยทั่วไปแล้วคุณจะไม่พบกับปัญหาที่ยากลำบาก