安全的HTML表单接受charset?

时间:2013-03-07 18:04:27

标签: html forms spring-mvc character-encoding

我在使用get方法提交表单时面临参数编码问题(我不能使用post方法)。由于我的页面是UTF8,因此URL中没有转义一些突出显示的字符。 Spring控制器改为检索坏字符。

我通过在我的表单上设置accept-charset="ISO-8859-1"解决了这个问题,但现在,我想知道哪个charset对于所有服务器/浏览器组合安全。有没有推荐我的表格和“获取”网址?

3 个答案:

答案 0 :(得分:7)

这对于servlet来说是令人沮丧的(温和地说)。标准URL编码必须使用UTF-8但servlet不仅默认为ISO-8859-1,而且不提供任何方法来改变代码。

当然,您可以在阅读任何内容之前req.setRequestEncoding("UTF-8"),但对于某些不敬虔的原因,这只会影响请求正文,而不会影响查询字符串参数。 servlet请求接口中没有任何内容可以指定用于查询字符串参数的编码。

在表单中使用ISO-8859-1是一种黑客行为。使用这种古老的编码会导致比解决问题更多的问题。特别是因为浏览器不支持ISO-8859-1并且始终将其视为Windows-1252。虽然servlet将ISO-8859-1视为ISO-8859-1,但如果你坚持下去,你将无法相信。

例如,要在Tomcat中更改此设置,您可以使用URIEncoding元素中的<connector>属性:

<connector ... URIEncoding="UTF-8" ... />

如果您不使用具有这些设置的容器,无法更改其设置或其他问题,您仍然可以使其正常工作,因为ISO-8859-1解码会保留原始二进制文件中的完整信息。

String correct = new String(request.getParameter("test").getBytes("ISO-8859-1"), "UTF-8")

让我们说test=ä如果一切都设置正确,浏览器会将其编码为test=%C3%A4。您的servlet将错误地将其解码为ISO-8859-1,并为您提供结果字符串"ä"。如果您应用更正,则可以返回ä

System.out.println(new String("ä".getBytes("ISO-8859-1"), "UTF-8").equals("ä"));
//true

答案 1 :(得分:2)

nickdos是对的。 另一种方法是使用元数据标记:

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">

在处理服务器上的响应时,请记住,代码也应该使用正确的(相同)编码。

示例:

使用stringParamer.getBytes("utf-8") instead of stringParamer.getBytes()

使用Spring时,请确保在DispatcherServlet的配置文件(XYZ_-servlet.xml)中为消息转换器配置了正确的编码,例如:

<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter">
    <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8"/>
</bean>

答案 2 :(得分:1)

问题是URL总是被编码为127-ASCII。由于您的表单会通过GET发送回标准ASCII设置之外的其他字符值,因此您会遇到一些问题:

  1. URL的长度限制为2048个字符,因此您的表单值可能会被截断
  2. 如果用户输入的字符超出了您在Form属性中设置的ISO接受类型,则这些字符将无法正确编码到URL中。这是因为浏览器在首次使用页面编码后对URL进行编码时,会将所有内容转换为127-ASCII。不在该ISO集中的任何特殊字符都将被错误编码。
  3. 浏览器始终始终首先使用页面编码或元标记来翻译URL中的字符。但是,如果有服务器HTTP标头,则该编码将覆盖您的元标记编码。 HTML5页面的默认编码为UTF-8。但是,您正在使用覆盖该标准的ISO标准。即使这样,您的浏览器完成的所有编码也会将非ASCII字符替换为“%”,后跟页面编码或您的表单设置编码中的十六进制数字。然后将其发送到服务器,因此请查看您的URL以查看已发送的内容。
  4. 当您的URL进入服务器时,它以127-ASCII输入,因此您需要首先将字符串作为ASCII进行获取,然后解码回页面编码,或者在您的情况下,Form接受用于获取真实的价值。

我建议您删除表单编码,使用页面UTF-8设置以获得更广泛的字符支持,并在下面添加这两个元标记,以确保您发送回UTF-8编码的数据,其中包括所需的所有字符和如上文其他海报所述,可以很容易地在服务器上对其进行解码。

<meta charset="utf-8" />
<meta content="text/html; charset=utf-8" http-equiv="content-type" />