热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

解决ajax提交表单出现乱码的问题

问题在现有主站中使用的是是GBK编码的,当表单使用formsubmit方式递交的话没有问题,服务器端能够正确识别字符编码。但是,当客户端使用ajax的方式递交表单的话,服务器端识别客户端递交的表单的内容,当内容中有中文字符的话就会出现乱码现象。原因分析
问题

在现有主站中使用的是是GBK编码的,当表单使用form submit方式递交的话没有问题,服务器端能够正确识别字符编码。但是,当客户端使用ajax的方式递交表单的话,服务器端识别客户端递交的表单的内容,当内容中有中文字符的话就会出现乱码现象。

原因分析

究其原因,其实很简单,使用ajax方式提交的表单是用utf-8编码来提交的,这样服务器端在接收客户端表单的内容的时候还是按照GBK或其他编码方式来解析的,自然解析出来的内容会出现乱码了。

表单内容可以通过GET或POST方式发送,但是用这两种方式有几个不同之处,对“你好”调用Javascript函数encodeURI()解析之后得到的字符串为“%E4%BD%A0%E5%A5%BD”,需要注意的一点,encodeURI()这个函数只会对字符串进行utf8编码。当客户端把“%E4%BD%A0%E5%A5%BD”这段字符串通过GET或者POST方式发送会发生什么事。

1.GET方式

当用get方式提交表单,在服务端的tomcat服务器中会用一个connector来自动解析编码之后字符串,以下是connector的配置节点:


 maxHttpHeaderSize="8192"
 maxThreads="150" minSpareThreads="25"
 maxSpareThreads="75"
 enableLookups="false" redirectPort="8443"
 acceptCount="100"
 cOnnectionTimeout="20000" disableUploadTimeout="true"
 URIEncoding="GBK" />


上面配置中有一个属性URIEncoding="GBK"的作用是,当客户端get发送信息中有encode模式的字符串就是用gbk来decode它。和遗憾,主站服务器中的URIEncoding属性是gbk不能变了,而客户端encodeURI()只能编码UTF-8的字符。所以,用这种方式发送的字符串在服务器端就会出现乱码现象。

2. POST方式

当客户端发送“%E4%BD%A0%E5%A5%BD”字符串时,是通过YAHOO.util.Connect这个控件来发送的,如果客户端能正常地发送“%E4%BD%A0%E5%A5%BD”这个字符串,服务端接收到之后并不会做额外的转义,但是YAHOO.util.Connect 将encode之后字符串传给Connect控件之后,这个控件在内部会将encode之后的字符再decode之后再发送,因为发送的是utf-8格式的内容,所以服务器端就会出现乱码。

解决办法

尝试了以上get和post方式之后,觉得在请求的URL上发送数据乱码问题的解决方案比较麻烦,况且,http协议中已经明确说了get和post的区别,get是从服务器端拿一些东西,而post是向服务器传输东西。get方式向服务器端发送数据的数据量有限,且get传输也是不安全的。

那么我们只能来解决YAHOO.util.Connect这个控件发送请求之前自动转义字符的问题。以下是Connect发送异步请求的一段代码


var postData="city="+from["city"].value
+"&areainfo="+from["areainfo"].value +"&store.name="+encodeURI(encodeURI(from["store.name"].value))
YAHOO.util.Connect.asyncRequest('POST',formObject.action, callback,postData);


如上所示,可以调用两遍encodeURI,

例如:“你好”

·调用一遍encodeURI:“%E4%BD%A0%E5%A5%BD”

·调用两遍encodeURI: “%25E4%25BD%25A0%25E5%25A5%25BD”

当把第二遍encode的结果传给YAHOO.util.Connect控件,控件会decode成第一遍调用encodeURI的输出结果,这样就能把“你好”的utf-8编码传输到服务器上去了。

在服务器的webwork的action或者interceptor中先对传输上来的内容做一次decode,注意一定要用utf-8解码。示例


try {
HttpServletRequest request
 = ServletActionContext.getRequest();
String storeName = request.getParameter("store.name");
this.getStore().setName(
  URLDecoder.decode(StringUtils.trimToEmpty(storeName)
    ,"UTF-8"));
this.getStore().setAddress(
 URLDecoder.decode(
  StringUtils.trimToEmpty(request
   .getParameter("store.address")), "UTF-8"));
} catch (Exception e) {
   throw new RuntimeException(e);
}


总结

通过以上提到的在客户端中将用ajax递交的字段内容两次调用encodeURI的方法,能够很好地解决服务器端使用非utf8的而造成的乱码问题。

出现这样的问题,主要原因是客户端Javascript的编码只支持utf编码,而服务器端能够按照架构师的需要定义各种编码,口碑现在服务器端使用的是GBK的编码格式,但是随着业务扩展,某些应用模块使用了utf的编码格式,这样在服务器端由于编码不统一,在做两个不同编码的格式系统的产品的时候给程序员带来了无尽的烦恼。例如,sa同时经常会问这样的问题,调用数据库的应用有用gbk编码的,也有用utf8编码的,那么数据库应该用啥编码的呢?

最近口碑的工程师们为现在一直为到底是用gbk编码还是用UTF8编码在进行讨论,我们现在讨论的焦点似乎是哪个编码更加好。但是我觉得,就编码来说扩展性当然是utf8,如果以后口碑要打入国际市场,到时候要出一个阿拉伯语版本的应用时候就可以轻松搞定了。我倒是觉得讨论那个编码好没有什么实际意义,关键是如何解决现在编码混乱的局面,如何让编码统一,这个才是我们应该关注的焦点。这样在将来的项目中我们的工程师不再会因为编码问题而头痛了。

所以我的个人观点是,当你开始搭建一个新的系统的时候,一开始就把utf-8作为你的项目中使用的编码格式,并且要把这个成为你项目的规约,写进你们项目组的“宪法”中去。这样,在以后会为你免去很多不必要的麻烦。


推荐阅读
  • 本文深入探讨了HTTP请求和响应对象的使用,详细介绍了如何通过响应对象向客户端发送数据、处理中文乱码问题以及常见的HTTP状态码。此外,还涵盖了文件下载、请求重定向、请求转发等高级功能。 ... [详细]
  • 本文介绍了多个关于JavaScript的书籍资源、实用工具和编程实例,涵盖从入门到进阶的各个阶段,帮助读者全面提升JavaScript编程能力。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • docker镜像重启_docker怎么启动镜像dock ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 如何配置Unturned服务器及其消息设置
    本文详细介绍了Unturned服务器的配置方法和消息设置技巧,帮助用户了解并优化服务器管理。同时,提供了关于云服务资源操作记录、远程登录设置以及文件传输的相关补充信息。 ... [详细]
  • 网络攻防实战:从HTTP到HTTPS的演变
    本文通过一系列日记记录了从发现漏洞到逐步加强安全措施的过程,探讨了如何应对网络攻击并最终实现全面的安全防护。 ... [详细]
  • 解决MongoDB Compass远程连接问题
    本文记录了在使用阿里云服务器部署MongoDB后,通过MongoDB Compass进行远程连接时遇到的问题及解决方案。详细介绍了从防火墙配置到安全组设置的各个步骤,帮助读者顺利解决问题。 ... [详细]
  • 在现代网络环境中,两台计算机之间的文件传输需求日益增长。传统的FTP和SSH方式虽然有效,但其配置复杂、步骤繁琐,难以满足快速且安全的传输需求。本文将介绍一种基于Go语言开发的新一代文件传输工具——Croc,它不仅简化了操作流程,还提供了强大的加密和跨平台支持。 ... [详细]
  • 云计算的优势与应用场景
    本文详细探讨了云计算为企业和个人带来的多种优势,包括成本节约、安全性提升、灵活性增强等。同时介绍了云计算的五大核心特点,并结合实际案例进行分析。 ... [详细]
  • 本文详细介绍了如何利用Go语言和WebSockets技术构建一个高效的实时聊天系统。随着网络应用的日益复杂化,实时交互成为了提升用户体验的关键要素之一。通过本指南,开发者可以学习到最新的技术和最佳实践。 ... [详细]
  • 本文将详细介绍通过CAS(Central Authentication Service)实现单点登录的原理和步骤。CAS由耶鲁大学开发,旨在为多应用系统提供统一的身份认证服务。文中不仅涵盖了CAS的基本架构,还提供了具体的配置实例,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 理解文档对象模型(DOM)
    本文介绍了文档对象模型(DOM)的基本概念,包括其作为HTML文档的节点树结构,以及如何通过JavaScript操作DOM来实现网页的动态交互。 ... [详细]
  • NFS(Network File System)即网络文件系统,是一种分布式文件系统协议,主要用于Unix和类Unix系统之间的文件共享。本文详细介绍NFS的配置文件/etc/exports和相关服务配置,帮助读者理解如何在Linux环境中配置NFS客户端。 ... [详细]
  • 本文将详细介绍如何在ThinkPHP6框架中实现多数据库的部署,包括读写分离的策略,以及如何通过负载均衡和MySQL同步技术优化数据库性能。 ... [详细]
author-avatar
逍遥子2502897751
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有