遇到的问题:Node.js JSON parsing error,syntax error unexpect end of input

测试代码



//测试/statuses/public_timeline接口   个人应用未审核会受限。使用SDK示例key
var json_sans_eval = require('./json_sans_eval');
var http = require('http');
var options = {
  host: 'api.weibo.com',
  port: 80,
  path: '/statuses/public_timeline.json?source=1306060637&count=2',
};

http.get(options, function(res) {
       res.on('data', function (chunk) {
         data = JSON.parse(""+chunk);
        console.log('BODY: ' + data.statuses[0].user.id)
  });
}).on('error', function(e) {
  console.log("Got error: " + e.message);
});




使用weibo的nodejs sdk的公共key去做访问,打印body无误,但是想解析chunk为json数据时出错

JSON全局对象在nodejs中是封装实现在v8引擎里的 http://code.google.com/p/v8/source/browse/trunk/src/json.js

尝试方法1:通过在线验证http://jsonlint.com/  结果是正确的json格式 、

尝试方法2:使用 git bash运行脚本,防止cmd GBK编码环境的影响,结果仍然error

尝试方法3:文本保存为json文件,通过fs分析


var fs=require('fs');
var data = fs.readFileSync('package.json', 'utf8')
console.log(JSON.parse(data).statuses[0].user)



也可以正确得出结果,不指定编码也没有问题

尝试方法4:使用nodejs demo,启动server和client,server发送简单的json格式数据无误,拷贝weibo json复杂数据,结果出错
尝试去掉 json数据的某个属性,使用nodejs server 发送数据,然后客户端去解析打印属性,可行。认为是某些字符编码有问题

查找编码问题:

eval("(" + chunk + ")"); 方式转换为字符串未果,出错

JSON.parse(chunk)会有字符非法问题,

JSON.stringify(chunk) 转换object为string后无法再解析出JSON数据

根据 http://www.openjs.com/scripts/data/json_encode.php 描述 从http://www.json.org/ 下载json_sans_eval.js并导入模块,

server端启动:


var http = require('http');
var weibostring = '{"statuses":[{"created_at":"Tue Feb 28 16:22:06 +0800 2012","id":3418080363744574,"mid":"3418080363744574","idstr":"3418080363744574","text":"一定要HOLD住!一定要每天给@羅志祥 “人气+1”,明星勋章我志在必得!快点来帮我一起给TA加人气吧! #我要TA的微群明星勋章#活动链接:http://t.cn/zO2ORjf","source":"<a href=\"http://q.weibo.com/\" rel=\"nofollow\">新浪微群</a>","favorited":false,"truncated":false,"in_reply_to_status_id":"","in_reply_to_user_id":"","in_reply_to_screen_name":"","thumbnail_pic":"http://ww1.sinaimg.cn/thumbnail/99c886d1jw1dqi27uys16j.jpg","bmiddle_pic":"http://ww1.sinaimg.cn/bmiddle/99c886d1jw1dqi27uys16j.jpg","original_pic":"http://ww1.sinaimg.cn/large/99c886d1jw1dqi27uys16j.jpg","geo":null,"user":{"id":2580055761,"idstr":"2580055761","screen_name":"干干干黄金客户","name":"干干干黄金客户","province":"44","city":"16","location":"广东 河源","description":"","url":"","profile_image_url":"http://tp2.sinaimg.cn/2580055761/50/0/1","profile_url":"u/2580055761","domain":"","weihao":"","gender":"m","followers_count":0,"friends_count":27,"statuses_count":1,"favourites_count":0,"created_at":"Sat Jan 14 00:00:00 +0800 2012","following":false,"allow_all_act_msg":false,"geo_enabled":true,"verified":false,"verified_type":-1,"allow_all_comment":true,"avatar_large":"http://tp2.sinaimg.cn/2580055761/180/0/1","verified_reason":"","follow_me":false,"online_status":1,"bi_followers_count":0,"lang":"zh-cn"},"reposts_count":0,"comments_count":0,"mlevel":0,"visible":{"type":0,"list_id":0}}],"hasvisible":false,"previous_cursor":0,"next_cursor":0,"total_number":1}'
http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'application/json'});
  response.end(weibostring);
}).listen(80);

console.log('Server running at http://127.0.0.1:80/');



client端:



var json_sans_eval = require('./json_sans_eval');
var http = require('http');
var options = {
  host: 'localhost',
  port: 80,
  path: '/'
};

http.get(options, function(res) {
       res.on('data', function (chunk) {
         data = json_sans_eval.jsonParse(""+chunk);
        console.log('BODY: ' + data.statuses[0].user.id)
  });
}).on('error', function(e) {
  console.log("Got error: " + e.message);
});



 

终于可用,但只是本地server可用(使用 json2.js 出现解析语法错误),但使用api.weibo.com  weibo接口仍然报错

尝试获取data.statuses[0].source发现问题 source内容被截断为<a href=  而不是  <a href=\"http://q.weibo.com/\" rel=\"nofollow\">新浪微群</a>

认为是js从字符串中重组json对象时无法区分 " 和 \"造成

使用python获取并加载为字典对象 完全没有问题



import httplib, urllib
import json
conn = httplib.HTTPConnection("api.weibo.com")
conn.request("GET", "/statuses/public_timeline.json?source=1306060637&count=2")
response = conn.getresponse()
data =  response.read()
data = json.loads(data)
print data['statuses'][0]['source']
conn.close()



nodejs sdk只有对接口输出的示例代码,没有重新解析为json对象的测试,format代码也只是使用JSON.parse方法。

最终不小心瞄了一眼打开未关的窗口http://ued.sina.com/?p=801,发现了自己的问题,不应该在 response的 data事件中去处理(数据可能正在发送中),而应该是end事件中再去做解析。



var body = '';
       res.on('data', function (chunk) {
         body += chunk
      });
      res.on('end',function(){
          weibo = JSON.parse(body)
        console.log(weibo.statuses[0].source)
      })



 

node-weibo, 由网友fengmk2提供(http://weibo.com/imk2 )  

source:https://github.com/fengmk2/node-weibo

该网友为python发烧友,ORZ!

 

通过这个很低级的错误,更清楚认识了nodejs的事件模型,也翻阅了json的学习资料

json相关网站:

老家:http://www.json.org/ 

json in javascript:http://www.json.org/js.html

 Mastering JSON ( JavaScript Object Notation ): http://www.hunlock.com/blogs/Mastering_JSON_(_JavaScript_Object_Notation_)