小菜我初学ajax,想做个用户名验证,结果一上手就遇到了传说中难以解决的乱码问题..
出现的问题是 中文查找查不到数据库数据
问题代码如下:
客户端关键代码:
xmlhttp = new GetXMLHttpObject();
var name = document.getElementById('username').value;
var url = "sql/findName.php";
var poststr="name="+name;
xmlhttp.open("POST",url,true);
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlhttp.send(poststr);
php端代码:
$name =$_POST['name'];
//发送header,将编码设为gb2312
header('Content-Type:text/html;charset=gb2312');
//连接MySQL服务器
$username=$_POST['username'];
$password=$_POST['password'];
$link=mysql_connect('localhost','root','123') or die('数据库服务器链接失败'+mysql_error());
mysql_select_db("student");
mysql_query("SET NAMES gb2312");
$sql = "select * from user where name='$name'";
$result=mysql_query($sql)or die('数据库服务器链接失败'+mysql_error());
$row=mysql_fetch_array($result);
if($row){
echo "1";
}else{
echo "0";
}
从网上搜索发现时编码问题...于是开始一一排查
首先猜测数据库出现了问题,但是之前
mysql_query("SET NAMES gb2312");
所以应该不会出现问题,排除!
找到了一些关于编码的知识,如utf-8是针对全球的,3字节一个。 gb2312是中国标准,国外跑是会乱码的,汉字站2字节,字母1字节等等
里面还提到 ajax是用utf-8进行编码,这点很重要啊。
于是乎我在想,把所有(无论html还是php的header函数)gb2312中设置改为utf-8,结果无果,还导致了浏览器虽然会以utf-8打开,但内容全部乱码,只有改回gb2312才能正常显示。此方法抛弃~(有大神懂为什么的指点下)
不过学到了header 和meat区别:
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
php中 header('Content-Type:text/html;charset=gb2312');
都可将向浏览器说明这是gb2312,但是header的到达浏览器速度比gb2312的快(不懂),
所以header的优先级高,当两者同时存在,以hedaer中charset为准
然后我又开始找到了一些转码的函数。
|--js中 编码函数:escape,encodeURI,encodeURIComponent。
对应解码函数:相应3个解码函数:unescape,decodeURI,decodeURIComponent。
|--php中iconv("UTF-8","gb2312",$username); 将 utf-8 变为 gb2312
还有 urlencode(); urldecode();
分别用于编码 URL 字符串和解码已编码的 URL 字符串,实现对中文字符的编码
其原理就是把中文字符转换为十六进制并按某种规则进行字符串组合,实现字符的编码与解编码,保证URL数据传递过程中字符的完整性和兼容性
但是并没有发现有能在js编码,又能在php解码的函数..很是郁闷,网上有些实现的函数,但是非常麻烦,表示看不懂。。
就在山穷水尽时,忽然想,其实本质问题就是传过来的是utf,而自己的是gb2312,之前是自己想多了。。
iconv("UTF-8","gb2312",$username);
应该就符合要求,为什么不行呢?
经过查询发现iconv函数执行过程中是很有可能执行错误的,一旦错误便不再进行下去,但是如果改为如下
$name = iconv("utf-8","gb2312//IGNORE",$name);
就会不管错误,继续往下执行iconv本身。于是乎转码成功!
通过一下午的努力,终于问题终于得到了解决。也学到许多和编码有关的知识。如果小菜文章里那里不对,希望大家多多指点