为啥 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 的视图技术,那么 &lt;!DOCTYPE html&gt; 也可以。


元标记:

<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 中的&lt;Connector&gt; 条目:

    <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 请求不成功?

CORS 请求 - 为啥不发送 cookie?

为啥不总是使用 HTTP post 进行 ajax 调用?

为啥PHP收不到AJAX发出的post请求

用jquery $.ajax 请求后台老是url %5Bobject%20Object%5D而报404错误,为啥?

为啥我的 Asp.Net Core 日志中出现“不支持 POST 请求”?