为啥 POST 不支持字符集,但 AJAX 请求可以?雄猫 6
Posted
技术标签:
【中文标题】为啥 POST 不支持字符集,但 AJAX 请求可以?雄猫 6【英文标题】:Why does POST not honor charset, but an AJAX request does? tomcat 6为什么 POST 不支持字符集,但 AJAX 请求可以?雄猫 6 【发布时间】:2011-05-22 12:18:39 【问题描述】:我有一个基于 tomcat 的应用程序,需要提交能够处理 utf-8 字符的表单。通过 ajax 提交时,数据从 utf-8 中的 getParameter() 正确返回。通过表单 post 提交时,数据从 iso-8859-1 中的 getParameter() 返回。
我使用了提琴手,并确定了请求中唯一的区别是 charset=utf-8 附加到 Content- 的末尾在 ajax 调用中键入 标头(正如预期的那样,因为我显式发送了内容类型)。
来自 ajax 的内容类型: "application/x-www-form-urlencoded; charset=utf-8"
来自表单的ContentType: "应用程序/x-www-form-urlencoded"
我有以下设置:
ajax post(正确输出字符):
$.ajax(
type : "POST",
url : "blah",
async : false,
contentType: "application/x-www-form-urlencoded; charset=utf-8",
data : data,
success : function(data)
);
form post(输出iso中的字符)
<form id="leadform" enctype="application/x-www-form-urlencoded; charset=utf-8" method="post" accept-charset="utf-8" action="//app/path">
xml声明:
<?xml version="1.0" encoding="utf-8"?>
文档类型:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
元标记:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
jvm参数:
-Dfile.encoding=UTF-8
我也尝试过使用 request.setCharacterEncoding("UTF-8"); 但似乎 tomcat 只是忽略了它。我没有使用 RequestDumper 阀门。
根据我的阅读,POST 数据编码主要取决于表单所在的页面编码。据我所知,我的页面以 utf-8 正确编码。
此页面中的示例 JSP 可以正常工作。它只是使用 setCharacterEncoding("UTF-8"); 并回显您发布的数据。 http://wiki.apache.org/tomcat/FAQ/CharacterEncoding
总而言之,尽管页面是 utf-8、指定 utf-8 的表单参数、xml 声明或其他任何内容,但 post 请求不会将字符集作为 utf-8 发送。我花了三天的大部分时间来解决这个问题,但我的想法已经不多了。谁能帮帮我?
【问题讨论】:
那么听起来这不是 tomcat 问题,而是浏览器问题,因为 tomcat 似乎能够正确处理传入的 UTF 请求,不是吗? Fiddler 是前 tomcat。你在不同的浏览器上试过吗? 在 firefox 3.6.12/linux、firefox 3.6.3/winxp、chrome 7.0.517.44/linux、8.0.552.215/winxp、safari 4.03 winxp 中测试。结果是一致的。 【参考方案1】:form post(输出iso中的字符)
<form id="leadform" enctype="application/x-www-form-urlencoded; charset=utf-8" method="post" accept-charset="utf-8" action="//app/path">
您无需在此处指定字符集。浏览器将使用 HTTP 中指定的字符集 响应头。
只是
<form id="leadform" method="post" action="//app/path">
够了。
xml声明:
<?xml version="1.0" encoding="utf-8"?>
无关紧要。它仅与 XML 解析器相关。 Webbrowsers 不会将 text/html
解析为 XML。这仅与服务器端相关(如果您使用基于 XML 的视图技术,如 Facelets 或 JSPX,在纯 JSP 上这是多余的)。
文档类型:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
无关紧要。它仅与 HTML 解析器相关。此外,它没有指定任何字符集。相反,将使用 HTTP 响应标头中的那个。如果您没有使用 Facelets 或 JSPX 等基于 XML 的视图技术,那么 <!DOCTYPE html>
也可以。
元标记:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
无关紧要。仅当从本地磁盘查看 HTML 页面或要在本地解析时才相关。相反,将使用 HTTP 响应标头中的那个。
jvm参数:
-Dfile.encoding=UTF-8
无关紧要。解析源文件只与 Sun/Oracle(!) JVM 相关。
我也尝试过使用
request.setCharacterEncoding("UTF-8");
,但似乎tomcat 只是忽略了它。我没有使用 RequestDumper 阀门。
这仅在请求正文尚未被解析时才有效(即您尚未事先调用getParameter()
等等)。您需要尽早调用它。 Filter
是一个完美的地方。否则会被忽略。
根据我的阅读,POST 数据编码主要取决于表单所在的页面编码。据我所知,我的页面以 utf-8 正确编码。
这取决于 HTTP 响应标头。
您需要做的就是以下三件事:
将以下内容添加到您的 JSP 顶部:
<%@page pageEncoding="UTF-8" %>
这会将响应编码设置为 UTF-8,并将响应标头设置为 UTF-8。
创建一个Filter
,它在doFilter()
方法中执行以下操作:
if (request.getCharacterEncoding() == null)
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
这将使 POST 请求正文将被处理为 UTF-8。
如下更改Tomcat/conf/server.xml
中的<Connector>
条目:
<Connector (...) URIEncoding="UTF-8" />
这将使 GET 查询字符串被处理为 UTF-8。
另见:
Unicode - How to get characters right? - 包含适用于 Java EE Web 开发人员的实用背景信息和详细解决方案。【讨论】:
本主题所有问题的最佳答案!request.setCharacterEncoding("UTF-8");
尽早(在过滤器中)帮助我解决了表单提交编码问题。【参考方案2】:
试试这个:
How do I change how POST parameters are interpreted?
POST 请求应指定它们发送的参数和值的编码。由于许多客户端无法设置显式编码,因此使用默认值 (ISO-8859-1)。在许多情况下,这不是首选的解释,因此可以使用 javax.servlet.Filter 来设置请求编码。编写这样的过滤器是微不足道的。此外,Tomcat 已经附带了这样一个示例过滤器。
请看:
5.x
webapps/servlets-examples/WEB-INF/classes/filters/SetCharacterEncodingFilter.java
webapps/jsp-examples/WEB-INF/classes/filters/SetCharacterEncodingFilter.java
6.x
webapps/examples/WEB-INF/classes/filters/SetCharacterEncodingFilter.java
更多信息,请参考以下网址 http://wiki.apache.org/tomcat/FAQ/CharacterEncoding
【讨论】:
这就是我用作参考的东西,并且已经用来最终解决问题。谢谢【参考方案3】:你试过accept-charset="UTF-8"
吗?如您所说,数据应根据页面本身的编码进行编码; tomcat忽略了这一点似乎很奇怪。你在哪个浏览器上试用?
【讨论】:
vivin,我在 firefox 3.6.12/linux、firefox 3.6.3/winxp、chrome 7.0.517.44/linux、8.0.552.215/winxp、safari 4.03/winxp 中试过这个。我确实尝试过 accept-charset="UTF-8" ,它没有明显的效果。【参考方案4】:您是否尝试在 conf/server.xml
中为 HTTP 连接器指定 useBodyEncodingForURL="true"
?
【讨论】:
这是一个 POST 正文,正文作为 ISO 发送,所以我认为将 url 字符串本身编码为与正文相同会有所帮助,但我会尝试一下。跨度> 【参考方案5】:我根据this post 中的信息实现了一个过滤器,它现在正在工作。但是,这仍然不能解释为什么即使页面是 UTF-8,tomcat 用来解释它的字符集是 ISO-9951-1。
【讨论】:
你的浏览器是什么?它也可能取决于客户端软件以上是关于为啥 POST 不支持字符集,但 AJAX 请求可以?雄猫 6的主要内容,如果未能解决你的问题,请参考以下文章
如何确定为啥 jQuery ajax $.post 请求不成功?