簡體   English   中英

HttpUtility.UrlEncode是否符合'x-www-form-urlencoded'的規范?

[英]Does HttpUtility.UrlEncode match the spec for 'x-www-form-urlencoded'?

每個MSDN

URLEncode轉換字符如下:

  • Spaces()轉換為加號(+)。
  • 非字母數字字符轉義為十六進制表示。

這與W3C類似,但不完全相同

應用程序/ x-WWW窗體-urlencoded

這是默認的內容類型。 使用此內容類型提交的表單必須按如下方式編碼:

  1. 控制名稱和值將被轉義。 空格字符由'+'替換,然后保留字符按RFC1738第2.2節中的描述進行轉義:非字母數字字符由'%HH'替換,百分號和兩個十六進制數字表示字符的ASCII代碼。 換行符表示為“CR LF”對(即'%0D%0A')。

  2. 控件名稱/值按它們在文檔中出現的順序列出。 名稱通過'='與值分隔,名稱/值對通過'&'彼此分隔。

我的問題是,是否有人完成了確定URLEncode是否生成有效的x-www-form-urlencoded數據的工作?

好吧,你鏈接到的文檔是針對IIS 6 Server.UrlEncode的,但是你的標題似乎詢問了.NET System.Web.HttpUtility.UrlEncode 使用像Reflector這樣的工具,我們可以看到后者的實現,並確定它是否符合W3C規范。

這是最終調用的編碼例程(注意,它是為一個字節數組定義的,其他重載使得字符串最終將這些字符串轉換為字節數組並調用此方法)。 您可以為每個控件名稱和值調用此方法(以避免轉義保留字符= &用作分隔符)。

protected internal virtual byte[] UrlEncode(byte[] bytes, int offset, int count)
{
    if (!ValidateUrlEncodingParameters(bytes, offset, count))
    {
        return null;
    }
    int num = 0;
    int num2 = 0;
    for (int i = 0; i < count; i++)
    {
        char ch = (char) bytes[offset + i];
        if (ch == ' ')
        {
            num++;
        }
        else if (!HttpEncoderUtility.IsUrlSafeChar(ch))
        {
            num2++;
        }
    }
    if ((num == 0) && (num2 == 0))
    {
        return bytes;
    }
    byte[] buffer = new byte[count + (num2 * 2)];
    int num4 = 0;
    for (int j = 0; j < count; j++)
    {
        byte num6 = bytes[offset + j];
        char ch2 = (char) num6;
        if (HttpEncoderUtility.IsUrlSafeChar(ch2))
        {
            buffer[num4++] = num6;
        }
        else if (ch2 == ' ')
        {
            buffer[num4++] = 0x2b;
        }
        else
        {
            buffer[num4++] = 0x25;
            buffer[num4++] = (byte) HttpEncoderUtility.IntToHex((num6 >> 4) & 15);
            buffer[num4++] = (byte) HttpEncoderUtility.IntToHex(num6 & 15);
        }
    }
    return buffer;
}

public static bool IsUrlSafeChar(char ch)
{
    if ((((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))) || ((ch >= '0') && (ch <= '9')))
    {
        return true;
    }
    switch (ch)
    {
        case '(':
        case ')':
        case '*':
        case '-':
        case '.':
        case '_':
        case '!':
            return true;
    }
    return false;
}

例程的第一部分計算需要替換的字符數(空格和非URL安全字符)。 例程的第二部分分配一個新的緩沖區並執行替換:

  1. Url安全字符保持原樣: az AZ 0-9 ()*-._!
  2. 空格轉換為加號
  3. 所有其他字符都轉換為%HH

RFC1738聲明(強調我的):

因此,只有字母數字,特殊字符“$ -_。+!*'(),”和
可以使用用於其保留目的的保留字符
在URL中未編碼。

另一方面,不需要編碼的字符
(包括字母數字)可以在特定方案內編碼
URL的一部分,只要它們不用於保留
目的。

UrlEncode允許的Url安全字符集是RFC1738中定義的特殊字符的子集。 也就是說,字符$,缺失並且將由UrlEncode編碼,即使規范說它們是安全的。 由於它們可能是未編碼的(而不是必須的 ),它仍然符合編碼它們的規范(第二段明確說明)。

關於換行符,如果輸入具有CR LF序列,那么將轉義%0D%0A 但是,如果輸入只有LF那么將轉義%0A (因此在此例程中沒有換行標准化)。

底線:它符合規范,同時另外編碼$,並且調用者負責在輸入中提供適當規范化的換行符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM