采用js对URL中的汉字进行escape编码
<a href="" onclick="windowopen(product_listphp?p_sort=+escape(脚本之家));">这样点击链接后的效时
引用%uF%uD%uD%uE%uF
生成了这样的效果 很明显用PHP的urldecode()或者base_decode()是无法反解的
解决方法 用PHP写一个反解函数
复制代码 代码如下:
function js_unescape($str){
$ret =
;
$len = strlen($str);
for ($i =
; $i < $len; $i++)
{
if ($str[$i] ==
%
&& $str[$i+
] ==
u
)
{
$val = hexdec(substr($str
$i+
));
if ($val <
x
f) $ret
= chr($val);
else if($val <
x
) $ret
= chr(
xc
|($val>>
))
chr(
x
|($val&
x
f)); else $ret
= chr(
xe
|($val>>
))
chr(
x
|(($val>>
)&
x
f))
chr(
x
|($val&
x
f));
$i +=
;
}
else if ($str[$i] ==
%
)
{
$ret
= urldecode(substr($str
$i
));
$i +=
;
}
else $ret
= $str[$i];
}
return $ret;}
注意JS编码会自动转换成为UTF 所以必须进行编码转换才能得到正确的结果否则会中文乱码但如果使用UTF-编码就不用这一步了
代码如下print iconv(utf gb js_unescape($_REQUEST[p_sort]));
到此我们就成功地反解了js的escape编码了
如下
另外我找到个用PHP实现js的escape编码的函数
复制代码 代码如下:
function phpescape($str)
{
$sublen=strlen($str);
$retrunString="";
for ($i=
;$i<$sublen;$i++)
{
if(ord($str[$i])>=
)
{
$tmpString=bin
hex(iconv("gb
"
"ucs
"
substr($str
$i
)));
//$tmpString=substr($tmpString
)
substr($tmpString
);window下可能要打开此项
$retrunString
="%u"
$tmpString;
$i++;
} else
{
$retrunString
="%"
dechex(ord($str[$i]));
}
}
return $retrunString;
}
在 json中不支持中文用它传送中文数据就会出现数据丢失或者乱码必须在传 送前对要发送的字符串进行编码由于传送过去需要用js进行数据解析考虑到js中有unescape函数故若在php中有个escape函数对数据 进行编码在客户端用unescape进行 解码这样就会方便很多
先在网上搜索一把很多用php实现的escape函数大同小异比如下面一个
复制代码 代码如下:
function phpEscape($str) {
preg_match_all("/[x
xff]
|[x
x
f]+/"
$str
$r);
$ar = $r[
];
foreach($ar as $k=>$v) {
if(ord($v[
]) <
)
$ar[$k] = rawurlencode($v);
else
$ar[$k] = "%u"
bin
hex(iconv("GB
"
"UCS
"
$v));
}
return join(""
$ar);
}
这个函数可以很好的工作但是也许有新手不理解这个函数的原理(比如我)用起来总是不放心现在我就来解释一下这个函数的原理而且我认为拿别人的代码来复用好比站在了巨人的肩膀上但是若不理解别人的代码迟早要掉到地面上
第一句preg_match_all("/[x xff]|[xxf]+/"$str$r);这个是用正则表达式匹配 字符串中所有的字符[xxff] 匹配的是汉字x表示匹配字符的进制编码[ ] 是类选择符“” 表示任意一个字符这样[xxff]匹配的是两个字符其中第一个就是进制从到ff的字符而这恰好就是汉字编码的第一个字符这样 就能完整的匹配一个汉字关于unicode中汉字的编码大家可以到网上搜索一下同理[xxf]+英文字符串因为最早的英文是 ASCII编码编码值小于也就是进制的从到f"+"表示一个或者多个字符这样[xxf]+就能匹配连续多个英文字符 串
复制代码 代码如下:
$ar = $r[
]; //$r[
]里存放是匹配到的数组
foreach($ar as $k=>$v) {
if(ord($v[
]) <
) //假如字符编码值小于
说明是个英文字符
$ar[$k] = rawurlencode($v); //直接用rawurlencode编码
else
$ar[$k] = "%u"
bin
hex(iconv("GB
"
"UCS
"
$v)); //否则的话用iconv函数把汉字转变成ucs
编码
也就是unicode编码
}
在javascript中就可以用unescape来解码了
uuFFE 和ueufa来匹配中文
但好像前者包含汉字下的A¥等 后者可能是纯汉字
其中解码函数为
复制代码 代码如下:
function unescape($str) {
$str = rawurldecode($str);
preg_match_all("/%u
{
}|&#x
{
};|&#d+;|
+/U"
$str
$r);
$ar = $r[
];
foreach($ar as $k=>$v) {
if(substr($v
) == "%u")
$ar[$k] = iconv("UCS
"
"GBK"
pack("H
"
substr($v
)));
elseif(substr($v
) == "&#x")
$ar[$k] = iconv("UCS
"
"GBK"
pack("H
"
substr($v
)));
elseif(substr($v
) == "&#") {
$ar[$k] = iconv("UCS
"
"GBK"
pack("n"
substr($v
)));
}
}
return join(""
$ar);
}
一编码范围
GBK (GB/GB)
xxff GBK双字节编码范围
xxf ASCII
xaxff 中文
xxff 中文
UTF (Unicode)
ueufa (中文)
xxF (韩文
xACxDA (韩文)
uue (日文)
ps: 韩文是大于[ufa]的字符
正则例子:
preg_replace("/([xxff])/"""$str);
preg_replace("/([ueufa])/"""$str);