用ajax提交表单时中文乱码解决方案

简介:
掉坑里了,遭遇到了js与PHP对表单中中文编码、解码方法不统一的问题。
当年上学的时候,对ms很是不屑,总是想玩一些与众不同的东西,玩linux、freebsd,玩opera,玩C++builder。当我做了一个网络开发者,才发现自己曾经是多么的幼稚,才开始怀念IE一统天下的那段美好时光。做一个网络开发者最大的苦恼是什么?对我来说这个问题的答案是:不统一的标准。如果你也经历过下面这些事情,我想你会同意我的看法:
一个在IE下看起来很正常很美观的页面,在其它的浏览器中却一踏糊涂,反之亦然;
一段在IE下工作得很完美的js代码,在其它的浏览器中却一点反应都没有,反之亦然;
......
也许个性真的是学生才能玩的东西。
不说废话了,说说我遇到的这个问题吧。要做一个无刷新的评论,类似于discuz5.5中的无刷新回帖。在提交表单的时候遇到了问题,通过ajax提交到处理脚本的中文字符串被转成了utf-8的格式,于是在往数据库里执行插入的时候出现了乱码。搜了一把却没有发现解决方案,于是开始自己摸索,摸索的过程中写了下面的函数:

//将类似'%D5%E2%D5%E2%D5%E2%D5%E2%D5%E2%D5%E2'解码,返回一个正常的字符串
function chardecode($str,$sep='%')
{
 $string = str_replace($sep,'',$str);
 $len = strlen($string);
 $strdecode = '';
 for ($i=0;$i<$len;$i+=2){
  $num1 = substr($string,$i,2);
  $num1 = hexdec($num1);
  $i+=2;
  $num2 = substr($string,$i,2);
  $num2 = hexdec($num2);
  $strdecode .= chr($num1).chr($num2);
 }
 return $strdecode;
}
其实这个函数的作用类似于urlencode(),比它强的地方在于可以自己设置每个字符间的分隔符。代码已经足够简单了,用到了两个不太常用的函数,hexdex()和chr()。前者的作用是将一个16进制的数字转换成10进制,后者是将一个数字转换成对应的aiscII字符。
然而这个函数并没能帮我解决问题,乱码依旧。其实解决这个问题主要难点是发现问题到底出在哪里,我并不是一上来就发现中文字符被转成了utf-8格式,只能一点点的摸索,找到了原因这个问题也就不难解决了。
这里用的是pnews里的一个utf-8转gb2312的函数,放出来与大家共享:
function u2g( $instr ) {
 $fp = fopen( '../language/unicode-gb.tab', 'r' );
 $len = strlen($instr);
 $outstr = '';
 for( $i = $x = 0 ; $i < $len ; $i++ ) {
  $b1 = ord($instr[$i]);
  if( $b1 < 0x80 ) {
   $outstr[$x++] = chr($b1);
#   printf( "[%02X]", $b1);
  }
  elseif( $b1 >= 224 ) { # 3 bytes UTF-8
   $b1 -= 224;
   $b2 = ord($instr[$i+1]) - 128;
   $b3 = ord($instr[$i+2]) - 128;
   $i += 2;
   $uc = $b1 * 4096 + $b2 * 64 + $b3 ;
   fseek( $fp, $uc * 2 );
   $gb = fread( $fp, 2 );
   $outstr[$x++] = $gb[0];
   $outstr[$x++] = $gb[1];
#   printf( "[%02X%02X]", ord($gb[0]), ord($gb[1]));
  }
  elseif( $b1 >= 192 ) { # 2 bytes UTF-8
   printf( "[%02X%02X]", $b1, ord($instr[$i+1]) );
   $b1 -= 192;
   $b2 = ord($instr[$i]) - 128;
   $i++;
   $uc = $b1 * 64 + $b2 ;
   fseek( $fp, $uc * 2 );
   $gb = fread( $fp, 2 );
   $outstr[$x++] = $gb[0];
   $outstr[$x++] = $gb[1];
#   printf( "[%02X%02X]", ord($gb[0]), ord($gb[1]));
  }
 }
 fclose($fp);
 if( $instr != '' ) {
#  echo '##' . $instr . " becomes " . join( '', $outstr) . "<br>n";
  return join( '', $outstr);
 }
}
注意函数中用到了一个码表:unicode-gb.tab,附件中的就是了。使用的时候你得根据实际情况把函数中的第一句改成码表实际存放的位置。

     本文转自wfyang 51CTO博客,原文链接:http://blog.51cto.com/wfyang/28751 ,如需转载请自行联系原作者

相关文章
|
3月前
|
XML 前端开发 JavaScript
php中Ajax的简单使用,登录表单调用Ajax判断是否正确登录利用layer.msg进行提示
本文介绍了在PHP中如何使用Ajax进行登录表单的数据提交,并利用jQuery的$.post()方法与后端通信,以及使用layer.msg进行前端提示。
php中Ajax的简单使用,登录表单调用Ajax判断是否正确登录利用layer.msg进行提示
|
4月前
|
前端开发 JavaScript Java
SpringBoot+JQuery+Ajax实现表单数据传输和单文件或多文件的上传
关于如何在SpringBoot项目中结合JQuery和Ajax实现表单数据的传输以及单文件或多文件上传的教程。文章提供了完整的前后端示例代码,包括项目的`pom.xml`依赖配置、SpringBoot的启动类`App.java`、静态资源配置`ResourceConfig.java`、配置文件`application.yml`、前端HTML页面(单文件上传和多文件上传加表单内容)以及后端控制器`UserController.java`。文章最后展示了运行结果的截图。
251 0
SpringBoot+JQuery+Ajax实现表单数据传输和单文件或多文件的上传
|
存储 前端开发 JavaScript
HTTP进阶,Cookie,响应的回报结果含义,ajax,form表单,不同状态码代表的结果
HTTP进阶,Cookie,响应的回报结果含义,ajax,form表单,不同状态码代表的结果
HTTP进阶,Cookie,响应的回报结果含义,ajax,form表单,不同状态码代表的结果
|
JSON 前端开发 安全
ajax中实现访问url已阅即焚的解决方案(url动态参数、变量加密、常量不变、php加密解密、API访问验证方式)
ajax中实现访问url已阅即焚的解决方案(url动态参数、变量加密、常量不变、php加密解密、API访问验证方式)
292 0
|
JSON 前端开发 JavaScript
layui上传文件弹出请求上传接口出现异常的终极解决方案(v2.68版本、ajax底层逻辑修改、debug快速定位)
layui上传文件弹出请求上传接口出现异常的终极解决方案(v2.68版本、ajax底层逻辑修改、debug快速定位)
1530 0
|
前端开发 API PHP
ajax获取API数据出现400或415的解决方案
ajax获取API数据出现400或415的解决方案
132 0
|
前端开发 API PHP
漏刻有时开放平台数据接口php允许ajax跨域的解决方案
漏刻有时开放平台数据接口php允许ajax跨域的解决方案
57 0
|
前端开发 JavaScript
javascript使用ajax传递token参数的一个解决方案
javascript使用ajax传递token参数的一个解决方案
130 0
|
前端开发
大数据量学习:ajax获取数据后将数组重新分组后分批定时渲染的解决方案
大数据量学习:ajax获取数据后将数组重新分组后分批定时渲染的解决方案
105 0
|
前端开发 数据可视化 JavaScript
ajax刷新php后台实现定时任务的执行解决方案
ajax刷新php后台实现定时任务的执行解决方案
104 0