AJAX POST调用Web服务时含单引号字符串被转义为'的问题求助
问题分析与解决方案
你遇到的问题根源有两个:一是JSON序列化时会自动转义单引号('变成'),二是直接在前端构造SQL条件字符串并拼接的做法存在严重的SQL注入风险,同时也会导致后端解析SQL时出现语法错误。
为什么会出现'?
当你用JSON.stringify处理包含单引号的字符串时,JSON规范会对特殊字符进行转义(虽然单引号在JSON字符串中不是强制转义的,但多数序列化库会默认这么做),所以后端收到的Criteria字段值会是转义后的字符串。如果后端直接把这个字符串拼到SQL语句里,就会出现类似FirstName LIKE N'%xxx'%'的语法错误——因为'会被当作字符串的一部分,而不是SQL的字符串分隔符。
正确的解决方案:改用参数化查询(强烈推荐)
永远不要在前端构造完整的SQL条件字符串,而是把搜索关键词和需要匹配的字段传给后端,由后端使用参数化查询来生成SQL。这种方式既解决了转义问题,又彻底避免了SQL注入攻击。
前端代码修改:
var searchKeyword = tblSYS_SubscribersSearch.value.trim(); var settings = { "url": "<%=ConfigurationManager.AppSettings["EndPoint"].ToString()%>" + "/api/SYS_Subscriber/GetListPaged", "method": "POST", "timeout": 0, "headers": { "Content-Type": "application/json" }, "data": JSON.stringify({ "ApiKey": Apikey, "Fields": Fields, // 传递搜索关键词和需要匹配的字段,而非完整SQL条件 "SearchKeyword": searchKeyword, "TargetFields": ["FirstName", "LastName"], "SortOrder": SortOrder, "SortDirection": SortDirection, "PageIndex": PageIndex, "PageSize": PageSize }), };
后端(C#)代码示例(以Dapper为例):
public class SubscriberQueryRequest { public string ApiKey { get; set; } public List<string> Fields { get; set; } public string SearchKeyword { get; set; } public List<string> TargetFields { get; set; } public string SortOrder { get; set; } public string SortDirection { get; set; } public int PageIndex { get; set; } public int PageSize { get; set; } } [HttpPost("api/SYS_Subscriber/GetListPaged")] public IActionResult GetListPaged([FromBody] SubscriberQueryRequest request) { // 基础SQL语句 var sqlBuilder = new StringBuilder($"SELECT {string.Join(", ", request.Fields)} FROM SYS_Subscribers WHERE 1=1"); var parameters = new DynamicParameters(); // 处理搜索条件(参数化) if (!string.IsNullOrEmpty(request.SearchKeyword)) { var conditionClauses = new List<string>(); foreach (var field in request.TargetFields) { var paramName = $"@{field}_Search"; // 使用参数化方式拼接模糊查询条件 conditionClauses.Add($"{field} LIKE N'%' + {paramName} + '%'"); parameters.Add(paramName, request.SearchKeyword); } sqlBuilder.Append($" AND ({string.Join(" OR ", conditionClauses)})"); } // 处理排序和分页 sqlBuilder.Append($" ORDER BY {request.SortOrder} {request.SortDirection.ToUpper()}"); sqlBuilder.Append($" OFFSET {request.PageIndex * request.PageSize} ROWS FETCH NEXT {request.PageSize} ROWS ONLY"); // 执行参数化查询 using var connection = new SqlConnection(yourConnectionString); var subscribers = connection.Query(sqlBuilder.ToString(), parameters).ToList(); return Ok(subscribers); }
临时应急方案(不推荐,仅用于无法重构后端的场景)
如果你因为某些限制必须保留前端构造SQL条件的方式,可以在后端接收后将转义的'替换回',但这依然存在SQL注入风险,请谨慎使用:
// 后端接收后处理 request.Criteria = request.Criteria.Replace("'", "'");
内容的提问来源于stack exchange,提问作者Christos Bokos
相关产品推荐
相关产品推荐

