URL编码转换escape()/encodeURI()/encodeURIComponent

 在使用url进行参数传递时,经常会传递一些中文名的参数或URL地址,在后台处理时会发生转换错误。在有些传递页面使用GB2312,而在接收页面使 用UTF8,这样接收到的参数就可能会与原来发生不一致。使用服务器端的urlEncode函数编码的URL,与使用客户端javascript的 encodeURI函数编码的URL,结果就不一样。 escape() 方法:采用ISO Latin字符集对指定的字符串进行编码。所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符 在字符集表里面的编码的16进制数字)。比如,空格符对应的编码是%20。unescape方法与此相反。不会被此方法编码的字符: @ * / +

encodeURI() 方法:把URI字符串采用UTF-8编码格式转化成escape格式的字符串。不会被此方法编码的字符:! @ # $& * ( ) = : / ; ? + '

encodeURIComponent() 方法:把URI字符串采用UTF-8编码格式转化成escape格式的字符串。与encodeURI()相比,这个方法将对更多的字符进行编码,比如 / 等字符。所以如果字符串里面包含了URI的几个部分的话,不能用这个方法来进行编码,否则 / 字符被编码之后URL将显示错误。不会被此方法编码的字符:! * ( )
因此,对于中文字符串来说,如果不希望把字符串编码格式 转化成UTF-8格式的(比如原页面和目标页面的charset是一致的时候),只需要使用escape。如果你的页面是GB2312或者其他的编码,而 接受参数的页面是UTF-8编码的,就要采用encodeURI或者encodeURIComponent。

       另外,encodeURI/encodeURIComponent是在javascript1.5之后引进的,escape则在javascript1.0版本就有。
------------->以下内容转自http://www.friends8.com/base/200712/197.shtml?1251186442<----------------

今天状态比较好,修改友吧的一些必要功能时进展神速的顺利,却在开发过程中发现js编码后的中文,php接收页解码不了,在.net等其他语言中没碰到过,所以到处找朋友寻方。朋友给的解释大概如下:

1、页面编码本身有问题,比如两个页面的编码不统一【可以排除】,因为我已经都设置了charset为gb2312    

2、利用icon方法配合php自带的urldecode方法试试【测试失败,php压根就没想处理解码的意思】

3、是不是js和php的编解码逻辑不同导致的【确实是这个问题】

以上基本是废话,接下来详细诉说下解决方案。

据说js  escape后的编码默认是utf-8 【所以如果你的页面是gb2312的,解码成功后记得iconv进行编码转换,不然中文还是乱码】。有些人可能会 说了,那我直接不编码就传到目标页总可以吧。如果是js拼凑地址后进行的访问,我测试了还是不行的,如果是表单提交或许可以,我没试。这里在页面编码保持 一致的情况下,我们只能利用php写一个功能恰似js中unescape的方法来进行处理了,方法如下:

//处理JS escape 过来的中文
function js_unescape($str)
{
 $ret = '';
 $len = strlen($str);  for ($i = 0; $i < $len; $i++)
 {
  if ($str[$i] == '%' && $str[$i+1] == 'u')
  {
    $val = hexdec(substr($str, $i+2, 4));    if ($val < 0x7f) $ret .= chr($val);
    else if($val < 0x800) $ret .= chr(0xc0|($val>>6)).chr(0x80|($val&0x3f));
    else $ret .= chr(0xe0|($val>>12)).chr(0x80|(($val>>6)&0x3f)).chr(0x80|($val&0x3f));    $i += 5;
  }
  else if ($str[$i] == '%')
  {
    $ret .= urldecode(substr($str, $i, 3));
    $i += 2;
  }
  else $ret .= $str[$i];
 }
 return $ret;
}
// 这个函数就处理了js escape过来的中文编码,但是如果你是utf-8编码的,那么还是乱码,需要再进行下一步操作  $str=iconv('utf-8','gb2312',$str)到这里才正真处理完成。现在你就可以试下了,效果绝对OK ,顺便提一下的几个方 法,依次为中英文混合截字符串,判断是否中文,php模拟js escape方法。

// start 开始位置,从0开始 
// long = 0 则从start 一直取到字符串尾 
// ltor = true 时从左到右取字符,false 时到右到左取字符 
// $cn_len 中文字符按字节取还是字数取,如果按字数取,则一个中文当一个字节计算 

function csubstr(&$str, $start=0, $long=0, $ltor=true, $cn_len=2) { 
 if($long == 0) $long = strlen($str); 
 if($ltor == false) $str = cstrrev($str); 
 if($cn_len == 1) { 
  for($i=0, $fs=0; $i<$start; $fs++) 
   $i += (ord($str[$fs]) <= 0xa0) ? 1 : 0.5; 
  for($i=0, $fe=$fs; $i<$long; $fe++) 
   $i += (ord($str[$fe]) <= 0xa0) ? 1 : 0.5; 
  $long = $fe - $fs; 
 } 
 else { 
  $fs = (is_chinese($str, $start) == 1) ? $start - 1 : $start; 
  $fe = $long + $start - 1; 
  $end = ( is_chinese($str, $fe) == -1 ) ? $fe -1 : $fe; 
  $long = $end - $fs + 1; 
 } 
 $f_str = substr($str, $fs, $long); 
 if($ltor == false) $f_str = cstrrev($f_str); 
 return $f_str; 
}

function is_chinese(&$str, $location) { 
 $ch = true; 
 $i = $location; 
 while(ord($str[$i])>0xa0 && $i >= 0) { 
  $ch = !$ch; 
  $i --; 
 } 
 if($i != $location) { 
  $f_str = $ch ? 1: -1; 
 } 
 else { 
  $f_str = false; 
 } 
 return $f_str; 


//php模拟js的escape
function phpescape($str)
{
  $sublen=strlen($str);
  $retrunString="";
  for ($i=0;$i<$sublen;$i++)
  {
    if(ord($str[$i])>=127)
    {
       $tmpString=bin2hex(iconv("gb2312","ucs-2",substr($str,$i,2)));
       //$tmpString=substr($tmpString,2,2).substr($tmpString,0,2);window下可能要打开此项
       $retrunString.="%u".$tmpString;
       $i++;
    } else {
       $retrunString.="%".dechex(ord($str[$i]));
    }
  }
  return $retrunString;
}

--------------------------------------------------------------------------------------------------------------------------------
真是郁闷,PHP够麻烦的,搞ASP还没有这么多的编码烦恼,一换成PHP,不是这个编码就是那个编码,编来编去的,烦死人啦!!!!!!!!那个乐色搞出的PHP呀?????
300*300
 文章首页关于迷茫时代关于我写意人生
版权所有:迷茫时代 All rights reserved   
执行时间:0.00473 秒