在 Web 开发中,前端通过表单提交用户输入内容,后端接收并保存数据,这是一个最常见的流程。但有时候我们会遇到一个恼人的问题:用户输入的原始字符在传输过程中被转义,导致数据库里存的并不是用户真实输入,而是 HTML 实体形式。

例如:

  • 用户输入:——(全角破折号)
  • 数据库存的却是:—
  • 用户输入:&
  • 数据库存的却是:&

这种情况不仅破坏了数据的完整性,还可能影响后续的展示和业务逻辑。


一、问题成因

常见原因之一是前端使用了 jQuery 的 .serialize() 方法来序列化表单数据:

var formData = $("#form-dict-add").serialize();

.serialize() 会把表单内容转成 application/x-www-form-urlencoded 格式的字符串,例如:

afterUnitName=%E2%80%94%E2%80%94&afterSocialCode=123

这一串数据会在传输和后端解析过程中,可能被全局过滤器、框架配置甚至前端拦截器做 HTML 转义。最终,数据库拿到的就不是原始字符,而是被转义后的 —& 等。


二、解决思路

1. 使用 FormData 代替 .serialize()

.serialize() 不同,FormData 会以 原始二进制流 的方式提交数据,而不是 URL 编码格式,可以避免大部分转义问题。

示例代码:

var formData = new FormData($("#form-dict-add")[0]);$.ajax({url: "/adminzy/agricultural/addUnitChange.do",type: "POST",data: formData,processData: false,  // 阻止 jQuery 对数据的预处理contentType: false,  // 让浏览器自动设置 Content-Typesuccess: function(res) {console.log("提交成功", res);},error: function() {alert("提交失败");}
});

2. 前端确认编码

在 HTML 中保证统一编码,避免字符集不一致导致乱码或意外转义:

<meta charset="UTF-8">

3. 后端确认编码与解析

在 Java/Spring 环境下,可以通过以下配置避免转义问题:

  • 统一请求编码web.xml):
<filter><filter-name>encodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param>
</filter>
<filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
  • Tomcat Connector 配置server.xml):
<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"URIEncoding="UTF-8" />

三、调试方法

  1. 前端打印
console.log(formData.get("afterUnitName"));
  1. 后端打印
System.out.println("raw afterUnitName=" + request.getParameter("afterUnitName"));

如果这两步打印出来的字符和用户输入一致(全角/半角没变),说明已经解决。


四、总结

  • .serialize() 会对数据做 URL 编码,在某些情况下可能被转义,导致原始字符丢失。
  • FormData 是更稳妥的选择,尤其是对需要保持原始输入的场景(例如全角/半角、特殊符号)。
  • 保证 前后端统一编码为 UTF-8,避免字符集差异带来的二次转义。
  • 通过前后端打印日志,可以快速定位问题出在哪一环。

这样就能在保存时保留用户最原始的输入,避免数据库出现各种奇怪的转义符号。