มีความแตกต่างระหว่าง Server.UrlEncode และ HttpUtility.UrlEncode หรือไม่
มีความแตกต่างระหว่าง Server.UrlEncode และ HttpUtility.UrlEncode หรือไม่
คำตอบ:
HttpServerUtility.UrlEncode
จะใช้HttpUtility.UrlEncode
ภายใน ไม่มีความแตกต่างเฉพาะ เหตุผลของการมีอยู่Server.UrlEncode
คือความเข้ากันได้กับ ASP คลาสสิก
ฉันมีอาการปวดหัวอย่างมีนัยสำคัญกับวิธีการเหล่านี้ก่อนหน้านี้ฉันขอแนะนำให้คุณหลีกเลี่ยงการเปลี่ยนแปลงใด ๆUrlEncode
และแทนที่จะใช้Uri.EscapeDataString
- อย่างน้อยก็มีพฤติกรรมที่เข้าใจได้
มาดูกัน...
HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
//standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
// want, since you still need to
// escape special characters yourself
แต่สิ่งที่ฉันชอบส่วนตัวต้องเป็นHttpUtility.UrlPathEncode - สิ่งนี้เข้าใจยากจริงๆ มันเข้ารหัส:
นอกจากนี้ยังมีเอกสาร MSDN ที่เฉพาะเจาะจงอย่างน่ารัก "เข้ารหัสส่วนเส้นทางของสตริง URL สำหรับการส่ง HTTP ที่เชื่อถือได้จากเว็บเซิร์ฟเวอร์ไปยังไคลเอนต์" - โดยไม่อธิบายว่ามันทำอะไร คุณมีโอกาสน้อยที่จะยิงตัวเองด้วยการเดินเท้าด้วย Uzi ...
?
คนที่จะบอกว่าจะเข้ารหัสและทำหน้าที่เป็นตัวคั่นที่? สำหรับพื้นที่: ในทั้งสองกรณีพื้นที่อยู่ในแฮชดังนั้นการมีหรือไม่มีส่วนของคิวรีแบบสอบถามจึงไม่สำคัญ และในที่สุดมันก็อภัยไม่ได้เลยที่จะทำให้ Uri เสียหายเช่นเดียวกับในตัวอย่างที่สองที่มี% UrlPathEncode
วิธีการที่ borked ธรรมดาและไม่ควรนำมาใช้
ข้างหน้าอย่างรวดเร็วเกือบ 9 ปีนับตั้งแต่ปีนี้เป็นครั้งแรกที่ถามและในโลกของ .NET หลักและ .NET มาตรฐานที่ดูเหมือนว่าตัวเลือกที่พบมากที่สุดที่เรามีสำหรับ URL ที่เข้ารหัสเป็นWebUtility.UrlEncode (ใต้System.Net
) และUri.EscapeDataString ตัดสินโดยคำตอบที่ได้รับความนิยมมากที่สุดที่นี่และที่อื่น ๆUri.EscapeDataStringดูจะดีกว่า แต่มันคืออะไร ฉันทำการวิเคราะห์เพื่อทำความเข้าใจความแตกต่างและนี่คือสิ่งที่ฉันได้รับ:
WebUtility.UrlEncode
เข้ารหัสพื้นที่เป็น+
; ถอดรหัสว่ามันเป็นUri.EscapeDataString
%20
Uri.EscapeDataString
ร้อยละถอดรหัส!
, (
, )
และ*
; WebUtility.UrlEncode
ไม่.WebUtility.UrlEncode
เข้ารหัสร้อยละ~
; Uri.EscapeDataString
ไม่.Uri.EscapeDataString
โยน a UriFormatException
บนสายอักขระที่ยาวกว่า 65,520 ตัว; WebUtility.UrlEncode
ไม่. ( ปัญหาที่พบบ่อยกว่าที่คุณคิดโดยเฉพาะเมื่อจัดการกับข้อมูลในแบบฟอร์มที่เข้ารหัส URL )Uri.EscapeDataString
พ่นUriFormatException
บนตัวอักษรตัวแทนสูง ; WebUtility.UrlEncode
ไม่. (นั่นคือสิ่งที่ UTF-16 อาจเป็นเรื่องธรรมดาน้อยกว่ามาก)สำหรับจุดประสงค์ในการเข้ารหัส URL อักขระในหนึ่งใน 3 หมวดหมู่: unreserved (ถูกต้องตามกฎหมายใน URL); สงวนไว้ (ตามกฎหมาย แต่มีความหมายพิเศษดังนั้นคุณอาจต้องการเข้ารหัส) และทุกอย่างอื่น (ต้องเข้ารหัสเสมอ)
ตามRFCตัวละครที่สงวนไว้คือ::/?#[]@!$&'()*+,;=
และตัวละครที่ไม่ได้จองเป็นตัวอักษรและตัวเลข -._~
Uri.EscapeDataStringกำหนดภารกิจไว้อย่างชัดเจน:% - เข้ารหัสอักขระที่สงวนและผิดกฎหมายทั้งหมด WebUtility.UrlEncodeมีความคลุมเครือทั้งในคำจำกัดความและการนำไปใช้ ผิดปกติมันเข้ารหัสอักขระที่สงวนไว้บางตัว แต่ไม่ใช่ตัวอักษรอื่น ๆ (ทำไมเครื่องหมายวงเล็บและไม่ใช่วงเล็บเหลี่ยม) และคนแปลกหน้ายังคงเข้ารหัสที่ไม่ได้จองอย่างไร้เดียงสา~
อักขระที่
ดังนั้นฉันเห็นด้วยกับคำแนะนำที่เป็นที่นิยม - ใช้Uri.EscapeDataStringเมื่อเป็นไปได้และเข้าใจตัวละครที่สงวนไว้เช่น/
และ?
จะได้รับการเข้ารหัส หากคุณต้องการจัดการกับสตริงที่มีขนาดใหญ่โดยเฉพาะอย่างยิ่งกับเนื้อหาที่มีการเข้ารหัส URL คุณจะต้องถอยกลับไปที่WebUtility.UrlEncodeและยอมรับนิสัยใจคอของพวกเขาหรือหลีกเลี่ยงปัญหา
แก้ไข:ฉันได้พยายามที่จะแก้ไขทั้งหมดของนิสัยใจคอดังกล่าวข้างต้นในFlurlผ่านUrl.Encode
, Url.EncodeIllegalCharacters
และUrl.Decode
วิธีการคง สิ่งเหล่านี้อยู่ในแพ็คเกจหลัก (ซึ่งมีขนาดเล็กและไม่รวมเนื้อหา HTTP ทั้งหมด) หรือไม่ก็สามารถคัดลอกมาจากแหล่งที่มาได้ ฉันยินดีรับความคิดเห็น / ข้อเสนอแนะที่คุณมีต่อสิ่งเหล่านี้
นี่คือรหัสที่ฉันใช้เพื่อค้นหาอักขระที่ถูกเข้ารหัสแตกต่างกัน:
var diffs =
from i in Enumerable.Range(0, char.MaxValue + 1)
let c = (char)i
where !char.IsHighSurrogate(c)
let diff = new {
Original = c,
UrlEncode = WebUtility.UrlEncode(c.ToString()),
EscapeDataString = Uri.EscapeDataString(c.ToString()),
}
where diff.UrlEncode != diff.EscapeDataString
select diff;
foreach (var diff in diffs)
Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");
โปรดทราบว่าคุณไม่ควรใช้วิธีการใดวิธีการหนึ่งต่อไปนี้ ไลบรารี่การเขียนสคริปต์ต่อต้านไซต์ของ Microsoft รวมถึงการแทนที่HttpUtility.UrlEncode
และHttpUtility.HtmlEncode
ที่สอดคล้องกับมาตรฐานมากกว่าและปลอดภัยยิ่งขึ้น ในฐานะโบนัสคุณจะได้รับJavaScriptEncode
วิธีการเช่นกัน
Server.UrlEncode () มีไว้เพื่อให้เข้ากันได้ย้อนหลังกับ Classic ASP
Server.UrlEncode(str);
เทียบเท่ากับ:
HttpUtility.UrlEncode(str, Response.ContentEncoding);
เช่นเดียวกับการServer.UrlEncode()
โทรHttpUtility.UrlEncode()