最近在開發(fā)小程序的時(shí)候,發(fā)現(xiàn)從服務(wù)器返回的JSON數(shù)據(jù)有時(shí)候能解析,有時(shí)候解析不了。
1、前提描述
我們發(fā)現(xiàn),如果直接從服務(wù)器端返回JSON字符串,小程序收到的就會是object對象。像這樣:

這里直接返回的json字符串。

這里收到的是object。這可能是微信替我們轉(zhuǎn)好了,不多說。
2、問題描述
突然一次,程序跑卡住了,不往下跑了。于是發(fā)現(xiàn)返回的data并不是object了,而是一個(gè)看似JSON的字符串。

這里的data 看起來就是一個(gè)JSON字符串。

然后嘗試去
JSON.parse(data),解析失敗。委曲求全,eval('(' + data + ')')的方式去解析,發(fā)現(xiàn)是可以的。但這不是我想要的。繼續(xù)找問題。

通過微信開發(fā)工具調(diào)試模式下Network看到返回的東西前面有兩個(gè)小紅點(diǎn),鼠標(biāo)放上去彈出
\ufeff,搜索之,非法字符?
3、解決方法
從網(wǎng)上搜了下,如果用windows自帶的文本編輯器編輯過文件,就會自動添加上BOM頭,很難發(fā)現(xiàn) ,找了一段代碼,去掉BOM頭。
PS : 服務(wù)器我用的php環(huán)境
代碼鏈接 www.douban.com/note/332229277/

上傳代碼至服務(wù)器項(xiàng)目目錄 , 運(yùn)行發(fā)現(xiàn)原來是微信登錄提供的代碼帶有BOM頭。把代碼中的 $auto 改為 1 , 就可以刪除BOM頭了。問題解決。
PHP代碼附錄
class CheckDom {
private $auto;
public function index(){
header('content-Type: text/html; charset=utf-8');
if(isset($_GET['dir'])){//設(shè)置文件目錄,如果沒有設(shè)置,則自動設(shè)置為當(dāng)前文件所在目錄
$basedir=$_GET['dir'];
}else{
$basedir='.';
}
$this->auto=0;/*設(shè)置為1標(biāo)示檢測BOM并去除,設(shè)置為0標(biāo)示只進(jìn)行BOM檢測,不去除*/
echo'當(dāng)前查找的目錄為:'.$basedir.'當(dāng)前的設(shè)置是:';
echo$this->auto?'檢測文件BOM同時(shí)去除檢測到BOM文件的BOM':'只檢測文件BOM不執(zhí)行去除BOM操作';
$this->checkdir($basedir);
}
function checkdir($basedir){
if($dh=opendir($basedir)){
while(($file=readdir($dh)) !==false){
if($file!='.'&&$file!='..'){
if(!is_dir($basedir.'/'.$file)){
echo'文件: '.$basedir.'/'.$file.$this->checkBOM($basedir.'/'.$file).'';
}else{
$dirname=$basedir.'/'.$file;
$this->checkdir($dirname);
}
}
}
closedir($dh);
}
}
function checkBOM($filename){
$contents=file_get_contents($filename);
$charset[1]=substr($contents,0,1);
$charset[2]=substr($contents,1,1);
$charset[3]=substr($contents,2,1);
if(ord($charset[1])==239&& ord($charset[2])==187&&ord($charset[3])==191){
if($this->auto==1){
$rest=substr($contents,3);
$this->rewrite($filename,$rest);
return(' 找到BOM并已自動去除');
}else{
return(' 找到BOM');
}
}else{
return(' 沒有找到BOM');
}
}
function rewrite($filename,$data){
$filenum=fopen($filename,'w');
flock($filenum,LOCK_EX);
fwrite($filenum,$data);
fclose($filenum);
}
}
?>