2009-08-17 57 views
5

Tôi đang triển khai viết lại URL trong ASP.net và các URL của tôi đang khiến tôi trở thành một thế giới có vấn đề.Mã hóa URL ASP.Net

URL được tạo từ cơ sở dữ liệu của các phòng ban & danh mục. Tôi muốn nhân viên có thể thêm các mục vào cơ sở dữ liệu với bất kỳ ký tự đặc biệt nào là thích hợp mà không làm hỏng trang web.

Tôi đang mã hóa dữ liệu trước khi tôi tạo URL.

Có một số vấn đề ...

  1. IIS giải mã URL trước khi nó đạt .net làm cho nó không thể phân tích đúng bất cứ điều gì với một "/" trong đó.
  2. ASP.net bị nhầm lẫn bởi việc tạo url "~" vô dụng trong các trang nhất định
  3. Tôi di chuyển từ máy chủ thử nghiệm được xây dựng sang máy chủ IIS cục bộ (máy XP) và bất kỳ URL nào có mã hóa & (% 26) cho tôi lỗi "Yêu cầu không hợp lệ".
  4. UrlEncode để lại một số ký tự bị hỏng không bị chạm vào như '.'

Tôi đã có hai bài đăng liên quan khác về chủ đề này, tại thời điểm tôi chỉ thấy các vấn đề nhỏ không phải là vấn đề lớn ở thượng nguồn. Tôi đã tìm thấy một số thủ thuật đăng ký để giải quyết vấn đề "Yêu cầu không hợp lệ" nhưng tôi sẽ triển khai một môi trường lưu trữ được chia sẻ khiến việc đó trở nên vô ích. Tôi cũng biết rằng đây là một sửa chữa cho một số vấn đề an ninh vì vậy tôi không muốn nhất thiết bỏ qua nó mà không biết những gì có thể của sâu tôi đang mở.

Thay vì cố gắng buộc. Net chuyển cho tôi url thô hoặc ghi đè cài đặt IIS, tôi muốn tạo URL thực sự an toàn ngay từ đầu.

Tôi sẽ lưu ý rằng tôi đã thử AntiXss.URLEncode, HttpUtility.URLEncode, URI.EscapeDataString. Tôi thậm chí đã thử những thứ ngu ngốc như doubleEncodng. Có một tiện ích nào làm những gì tôi cần, hay tôi thực sự cần phải cuộn của riêng tôi. Tôi thậm chí còn đang cân nhắc việc làm một cái gì đó Hacky như thay thế% bằng một chuỗi ký tự khác thường. Kết quả cuối cùng nên ít nhất là có thể đọc được mà là điểm của việc sử dụng viết lại URL ở nơi đầu tiên.

Xin lỗi vì bài đăng dài- Tôi chỉ muốn đảm bảo rằng tôi đã bao gồm tất cả các chi tiết cần thiết. Tôi dường như không thể tìm thấy bất kỳ thông tin liên quan về điều này, và có vẻ như nó sẽ là một vấn đề phổ biến - vì vậy có lẽ tôi đang thiếu một cái gì đó lớn. Cảm ơn sự giúp đỡ của bạn, và kiên nhẫn với lời giải thích dài!


Chỉnh sửa cho rõ ràng:

Khi tôi nói các url đang được xây dựng từ một cơ sở dữ liệu những gì tôi có nghĩa là cấu trúc thư mục được contstructed từ các phòng ban và chuyên mục trong cơ sở dữ liệu của tôi.

Một số Ví dụ URL -

Mystore/lạnh/Bar + Fridge.aspx
Mystore/Nấu ăn + Equipment.aspx
Mystore/Bếp/Cắt + Boards.asxpx

Những vấn đề đi trong khi Tôi sử dụng một bộ phận như "Đồ uống & Bar" hoặc "Pastry/Decorating" để tạo URL của tôi. Mặc dù được mã hóa đầu tiên, những nguyên nhân này đã gây ra những vấn đề nói trên.

Trình xử lý của tôi đã được triển khai và hoạt động tốt ngoại trừ các vấn đề về mã hóa ký tự đặc biệt.

+0

Trong sự quan tâm của toàn tiết lộ đây là posts- khác có liên quan của tôi http://stackoverflow.com/questions/1274669/ url-encoding-being-lost-before-processing-asp-net - Câu hỏi tương tự nhưng tôi đã cố gắng để buộc. net để cung cấp cho tôi URL gốc thay vì sửa mã hóa trên liên kết gốc. http://stackoverflow.com/questions/1194900/asp-net-path-problems-caused-by-encoded-urls Cố gắng khắc phục sự cố "~" trước khi tôi nhận ra rằng có vấn đề lớn hơn. –

Trả lời

4

Bạn nên cân nhắc việc có một bảng trong bảng danh mục/bộ phận của mình có một URL duy nhất cho từng danh mục. Sau đó, bạn có thể sử dụng một thường trình đặc biệt để tạo URL. Đây có thể là một hàm vô hướng SQL, hoặc một hàm CLR, nhưng một trong những điều nó sẽ làm là chuẩn hóa URL cho web. Bạn có thể chuyển đổi "Đồ uống & Bar" thành "Beverage-And-Bar" và "Pastry/Decorating" thành "Pastry-Decorating". Chủ yếu, các thói quen cần phải thay thế tất cả các ký tự URL HTTP không hợp lệ với một cái gì đó khác. Một ví dụ là:

public static class URL 
{ 
    static readonly Regex feet = new Regex(@"([0-9]\s?)'([^'])", RegexOptions.Compiled); 
    static readonly Regex inch1 = new Regex(@"([0-9]\s?)''", RegexOptions.Compiled); 
    static readonly Regex inch2 = new Regex(@"([0-9]\s?)""", RegexOptions.Compiled); 
    static readonly Regex num = new Regex(@"#([0-9]+)", RegexOptions.Compiled); 
    static readonly Regex dollar = new Regex(@"[$]([0-9]+)", RegexOptions.Compiled); 
    static readonly Regex percent = new Regex(@"([0-9]+)%", RegexOptions.Compiled); 
    static readonly Regex sep = new Regex(@"[\s_/\\+:.]", RegexOptions.Compiled); 
    static readonly Regex empty = new Regex(@"[^-A-Za-z0-9]", RegexOptions.Compiled); 
    static readonly Regex extra = new Regex(@"[-]+", RegexOptions.Compiled); 

    public static string PrepareURL(string str) 
    { 
     str = str.Trim().ToLower(); 
     str = str.Replace("&", "and"); 

     str = feet.Replace(str, "$1-ft-"); 
     str = inch1.Replace(str, "$1-in-"); 
     str = inch2.Replace(str, "$1-in-"); 
     str = num.Replace(str, "num-$1"); 

     str = dollar.Replace(str, "$1-dollar-"); 
     str = percent.Replace(str, "$1-percent-"); 

     str = sep.Replace(str, "-"); 

     str = empty.Replace(str, string.Empty); 
     str = extra.Replace(str, "-"); 

     str = str.Trim('-'); 
     return str; 
    } 
} 

Bạn có thể làm cho chức năng này tăng cường SQL hoặc chạy tạo URL dưới dạng một quy trình riêng biệt. Sau đó, để triển khai ánh xạ, bạn sẽ ánh xạ toàn bộ URL trực tiếp tới ID danh mục. Cách tiếp cận này tốt hơn trong thời gian dài vì nhiều lý do. Trước tiên, bạn không phải lúc nào cũng tạo URL, bạn làm điều này một lần và chúng vẫn tĩnh, bạn không phải lo lắng về việc thay đổi thủ tục của mình, và sau đó GoogleBot không thể tìm thấy các URL cũ. Ngoài ra, nếu bạn nhận được một vụ va chạm, bạn có thể nhận thấy một tên thể loại trùng lặp tiềm năng, bởi vì một vụ va chạm sẽ chỉ khác nhau bởi các ký tự đặc biệt. Cuối cùng, bạn luôn có thể xem URL của mình từ cơ sở dữ liệu mà không phải chạy hàm ánh xạ.

+1

Điều đó hoàn toàn hoàn hảo. Cảm ơn bạn rất nhiều, bạn đã tiết kiệm cho tôi nhiều thời gian hơn tôi quan tâm. –

1

Tôi có một url ghi đè tôi thực hiện trong tập tin global.asax trong yêu cầu bắt đầu xác thực khi tôi có một số bảo mật. Đây là nơi tôi lấy url thô và sau đó làm db nhìn lên. điều này sau đó viết lại đường dẫn đến trang aspx và tất cả các tham số được truyền qua chuỗi truy vấn. Không cần mã hóa.

Tuy nhiên nếu bạn đang sử dụng url để thực sự thay đổi dữ liệu thì tôi có thể thấy rằng bạn sẽ gặp phải các vấn đề lớn khi bạn đang sử dụng http GET để thay đổi cơ sở dữ liệu một cách hiệu quả. Nó thường được coi là một idead xấu, và không phải cái gì tôi làm.

Tôi chỉ sử dụng yêu cầu đăng bài để thực hiện bất kỳ thao tác dữ liệu nào. Điều này giúp url sạch sẽ vì tất cả dữ liệu ở dạng trang.

Vấn đề duy nhất tôi có là đặt url chính xác thành page.form.action, trong hầu hết các trường hợp, đó là url thô.

Nếu tên danh mục đang gây ra sự cố thì có lẽ bạn nên hạn chế tên chỉ thành các ký tự số alpha và không gian hoán đổi cho "-". IIS sẽ ném một cách lung lay với dấu chấm "." vì nó tìm kiếm tên tệp.

P.S. IIS không hiểu dấu ngã "~", đây là thứ mà trình biên dịch hiểu được. vì vậy nếu bạn sử dụng nó trong một thẻ neo nó sẽ không hoạt động như mong đợi và bạn nên sử dụng gốc ứng dụng thay vì dấu ngã.

Chỉnh sửa:

OK, có vẻ như vấn đề với IIS gặp sự cố với các ký tự nhất định như./và &. Thậm chí nếu bạn làm urlencode, IIS sẽ vẫn cố gắng thực hiện ý nghĩa riêng của nó. Như vậy xem xét tháo gỡ chúng chỉ như vậy:

đồ uống & thanh trở nên BeverageBar

Pastry/trang trí trở nên PastryDecorating.

Điều này sẽ giúp bạn luôn làm sạch url, nhưng có nghĩa là cột bổ sung trong cơ sở dữ liệu để bạn có thể cheack url so với tên danh mục rút gọn này.

+0

Xin lỗi tôi đã rõ ràng hơn - Tôi không thực hiện bất kỳ thao tác cơ sở dữ liệu nào với các URL của mình. Cửa hàng của tôi được chia thành các phòng ban và danh mục. Thay vì được mã hóa cứng cấu trúc thư mục được xây dựng từ cơ sở dữ liệu. Các menu khác nhau có các liên kết của mẫu Mystore/Department hoặc Mystore/Department/Category trong khi mã hóa và kỹ thuật chính xác đang bị phá vỡ bởi IIS trước khi yêu cầu thậm chí làm cho nó trở lại httpHandler của tôi. –

+0

Đó có thể là giải pháp tốt nhất. Tôi có thể chỉ là những thứ quá phức tạp. Mối quan tâm duy nhất của tôi là tôi sẽ cần phải có thể tra cứu các mục từ URL mà có thể phức tạp bằng một phương pháp mã hóa không thể đảo ngược. Ý tưởng duy nhất khác của tôi là sử dụng Uri.EscapeDataString (b) .Replace ("%", "_") mà tôi khá chắc chắn sẽ lên án tôi lập trình địa ngục. Cảm ơn bạn rất nhiều vì đã trả lời nhanh và trợ giúp về vấn đề này .. Tôi đang xem xét mã của mình để xem điều này có hiệu quả hay không. –

+0

Cảm ơn bạn rất nhiều vì sự giúp đỡ của bạn. Đây là một trong những thời điểm mà tôi vô cùng thất vọng vì tôi không thể chấp nhận nhiều câu trả lời. Bạn đã chỉ cho tôi đúng hướng và giúp tôi trở lại đúng hướng với điều này ... Cảm ơn bạn !! –

1

Tôi gặp vấn đề tương tự. Cảm ơn bạn đã viết nó rất đẹp. Nó thực sự đã giúp tôi hiểu vấn đề tốt hơn.

Tuy nhiên, tôi đã có một số cân nhắc khác. Một trong những mục tiêu tôi có là hỗ trợ tiềm năng cho bất kỳ nhân vật nào có trong url dựa trên tiêu đề của một bài viết. Ngoài ra tôi muốn đảm bảo tính duy nhất trong mã hóa và quá trình mã hóa/giải mã hai chiều.

Vì vậy, tôi đã thực hiện một số mã hóa thủ công để giải quyết vấn đề. Điều này sẽ không loại bỏ hoàn toàn phần trăm mã hóa, nhưng sẽ làm giảm đáng kể mã hóa và ngăn người dùng tạo ra một url không thể tiếp cận. Quá trình của tôi bắt đầu bằng cách sử dụng hàm Server.URLEncode. Nhưng điều này không loại bỏ các vấn đề trong url. Vì IIS đang giải mã url và sau đó chuyển nó tới ứng dụng, một số ký tự nhất định sẽ phá vỡ nó với một ngoại lệ yêu cầu nguy hiểm. Các ký tự này bao gồm +, &, /, !, *, ., (). Vì vậy, trên những nhân vật cộng với các nhân vật khác tôi muốn làm cho dễ đọc hơn tôi làm một mã hóa đôi cho một url có thể sử dụng nhiều hơn. Mã hóa cũng khó vì số lượng ký tự hạn chế được phép trong url. Vì vậy, trước khi mã hóa tôi đã thực hiện tất cả các chữ cái vốn và sau đó đã làm các mã hóa với trường hợp thấp hơn. Điều này giúp nó không thể giải mã hoàn toàn, nhưng tôi có thể dễ dàng thực hiện một kết hợp trong cơ sở dữ liệu hoặc trong mã bằng cách làm cho giá trị mà tôi muốn khớp là chữ hoa.

Vâng, đây là mã của tôi. Phản hồi sẽ được đánh giá cao. Oh ya, đây là trong VB, nhưng mọi thứ nên chuyển sang C# dễ dàng đủ.

Dim strReturn As String = Trim(strStringToEncode) 
strReturn = Server.UrlEncode(strReturn) 

strReturn = strReturn.Replace("-", "dash").Replace("+", "-") 

strReturn = strReturn.Replace("%26", "and"). 
        Replace("%2f", "or"). 
        Replace("!", "excl"). 
        Replace("*", "star"). 
        Replace("%27", "apos"). 
        Replace("(", "lprn"). 
        Replace(")", "rprn"). 
        Replace("%3b", "semi"). 
        Replace("%3a", "coln"). 
        Replace("%40", "at"). 
        Replace("%3d", "eq"). 
        Replace("%2b", "plus"). 
        Replace("%24", "dols"). 
        Replace("%25", "pct"). 
        Replace("%2c", "coma"). 
        Replace("%3f", "query"). 
        Replace("%23", "hash"). 
        Replace("%5b", "lbrk"). 
        Replace("%5d", "rbrk"). 
        Replace(".", "dot"). 
        Replace("%3e", "gt"). 
        Replace("%3c", "lt") 

Return strReturn 
+0

Đã tìm thấy sự cố. Quét URL từ chối báo giá thông minh duy nhất. – Nate

+0

Tìm thấy nhiều dấu ngoặc kép khiến urlscan trở nên điên rồ. Điều này sẽ giúp sửa chữa nó. Thay thế ("% e2% 80% 99", "rsquo"). Thay thế ("% e2% 80% 98", "lsquo"). Thay thế ("% e2% 80% 9d", "rdquo"). Thay thế ("% e2% 80% 9c", "ldquo"). Thay thế ("% e2% 80% 9b", "lsrquo"). Thay thế ("% e2% 80% 9f", "ldrquo"). – Nate

+0

Hãy xem các tham số web.config như 'requestFiltering allowDoubleEscaping =" true "' (http://stackoverflow.com/a/1453287/1178314) và 'httpRuntime requestValidationMode =" 2.0 "relaxUrlToFileSystemMapping =" true "requestPathInvalidCharacters =" " '. Trong trường hợp sử dụng của tôi, nó cho phép tôi hỗ trợ nhiều nhân vật hơn trong các url. –

0

Tôi đoán bạn đang tìm kiếm HttpUtility.UrlEncodeHttpUtility.HtmlDecode

string url = "http://www.google.com/search?q=" + HttpUtility.UrlEncode("Example"); 
+1

Cảm ơn các thông tin mặc dù vấn đề được nhiều hơn rằng urlencode/giải mã không hoạt động như asp.net hoặc iis vẫn từ chối các url được mã hóa. Tôi nghĩ rằng tôi đã kết thúc bằng cách sử dụng một kế hoạch thay thế thay vào đó, nhưng đây là một thời gian một đi vì vậy tôi là một chút mờ. –