前言
前端请求时做了个参数验证,就是简单的计算md5,但是与后端计算的结果始终不一致
发现是前后端对字符串排序的默认规则有区别
测试代码
前端
1、示例代码,可以在浏览器的控制台中直接运行
e=["","你","1","a","d","B","你好","你0","你d","你A",",","你."] e.sort((a, b) => (a > b ? 1 : a < b ? -1 : 0)); console.log(e);
2、运行结果
['', ',', '1', 'B', 'a', 'd', '你', '你.', '你0', '你A', '你d', '你好']
后端
1、示例代码
var arr = new string[] { "", "你", "1", "a", "d", "B", "你好", "你0", "你d", "你A", ",", "你." }; var r = "'" + string.Join("', '", arr.OrderBy(x => x)) + "'"; Console.WriteLine(r);
2、运行结果
'', ',', '1', '你', '你.', '你0', '你好', '你A', '你d', 'a', 'B', 'd'
分析规则
前端:
空 -> 标点符号 -> 数字 -> 大写字母 -> 小写字母 -> 汉字
后端:
空 -> 标点符号 -> 数字 -> 汉字 -> 字母(不区分大小写)
解决方案
方案1-自定义字符串对比规则
private static void SortByCompare(string[] arr) {var r = string.Join(" ", arr.OrderBy(x => x, new StringComparer()));Console.WriteLine(r); } public class StringComparer : IComparer<string> {public int Compare(string x, string y){int orderX = 0;int orderY = 0;if (!string.IsNullOrWhiteSpace(x))orderX = GetOrder(x[0]);if (!string.IsNullOrWhiteSpace(y))orderY = GetOrder(y[0]);if (orderX == orderY)return string.Compare(x, y, StringComparison.Ordinal);return orderX.CompareTo(orderY);}private int GetOrder(char c){if (char.IsPunctuation(c))return 10;if (char.IsDigit(c))return 20;else if (char.IsUpper(c))return 30;else if (char.IsLower(c))return 40;return 999;} }
方案2-使用V8引擎调用js方法
1、项目添加以下Nuget引用
Microsoft.ClearScript.Core
Microsoft.ClearScript.V8
Microsoft.ClearScript.V8.Native.win-x64
2、项目添加js文件,示例:calc.js,内容如下
function sortParameter(data) {if (!data) {return "";}var e = JSON.parse(data);e.sort((a, b) => (a > b ? 1 : a < b ? -1 : 0));return e.join(" "); }
3、编写方法
private static V8ScriptEngine _engine = new(); private static void SortByV8(string[] arr) {_engine.Execute(File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "calc.js"), Encoding.UTF8));string json = arr.ToJson();object r = _engine.Invoke("sortParameter", [json]);Console.WriteLine(r); }
验证
1、后端代码
var arr = new string[] { "", "123", "all", "delay", "Basic", ",./" };SortByCompare(arr); SortByV8(arr);
2、后端运行结果
,./ 123 Basic all delay
,./ 123 Basic all delay
3、前端代码
e=["", "123", "all", "delay", "Basic", ",./"] e.sort((a, b) => (a > b ? 1 : a < b ? -1 : 0)); console.log(e);
4、前端运行结果
['', ',./', '123', 'Basic', 'all', 'delay']
总结
按照这个场景,这2个方案都能实现,但也各有优劣。
方案1-自定义规则,
(1)是C#语言的实现,
(2)但只处理了首个字符的逻辑处理
(3)且未处理汉字的逻辑
方案2-V8引擎调用js
(1)比较重,单独引用了类库
(2)无须重新实现逻辑了,直接执行js的逻辑