繁体   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