当我们在.NET Core中处理URL编码的时候,有两个API可以选择:System.Net.WebUtility.UrlEncode 和 System.Web.HttpUtility.UrlEncode。他们有什么区别,我们又该选择哪个?我做了一些研究,本文是我的一些发现。
01
测试结果
首先,我们来看看测试。我测试了2对WebUtility和HttpUtility里相同的方法:
UrlEncode/UrlDecode 以及 HtmlEncode/HtmlDecode
唯一有区别的是UrlEncode(string)返回了不同的结果:
var webencode = System.Net.WebUtility.UrlEncode(test);
var httpencode = System.Web.HttpUtility.UrlEncode(test);
Console.WriteLine($"WebUtility.UrlEncode: {webencode}");
Console.WriteLine($"HttpUtility.UrlEncode: {httpencode}");
针对需要被编码的字符,WebUtility.UrlEncode()返回了大写,而HttpUtility.UrlEncode()返回的是小写。
02
这TM是怎么回事
感谢微软开源了.NET,我们能够通过查看.NET Core的源代码发现原因,源代码戳这里:https://github.com/dotnet/corefx
如果你想亲眼看看的话,代码路径如下:
WebUtility类
corefxsrcSystem.Runtime.ExtensionssrcSystemNetWebUtility.cs
HttpUtility类
corefxsrcSystem.Web.HttpUtilitysrcSystemWebHttpUtility.cs
WebUtility
我在408行找到了UrlEncode方法(行号可能会变,如果微软修改了源代码)
它会调用GetEncodedBytes()方法
而这里面又会调用IntToHex()方法
最终,我们能够发现,因为强转了一个大写字符'A',所以任何被编码的字符都会输出为大写。
HttpUtility
我对HttpUtility做了相同的分析,最终发现它调用了System.Web.Util.IntToHex()方法,代码如下:
这就解释了为啥它返回的总是小写字符。
我的猜想
我不知道这是否为刻意设计的,但有两个版本的IntToHex()方法让我比较懵逼。我更希望API能给调用者提供一个可选参数用来控制输出字符的大小写。
03
那么该选哪个方法呢?
简而言之,我自己的系统里全部使用小写URL。所以我会选择使用HttpUtility.UrlEncode()去编码URL。
在Windows系统里,URL的大小写是无所谓的。但是Linux里是不一样的,大小写不一致可能让你遇到404。而且,大写字符和小写字符的HASH是不一样的,如果你的系统里有某个地方通过HASH来校验URL,那么大小写问题会导致校验失败。
说到SEO的话,有些人可能认为小写是更加SEO友好的,但实际上URL大小写在Google这里是不影响排名的。不信可以看看论坛:
https://productforums.google.com/forum/#!topic/webmasters/ky1L_dj4n5c/discussion (嗯,好像这是个不存在的网站)
关键在于,你需要在自己的系统里保证URL大小写规则一致,并且留意与你的系统对接的其它系统,是否用了不同的URL大小写处理方式。