You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 21:02:46