最近用bottle写后台api接口,返回的都是json格式。后来写前端的同学说不能解析json,然后搜了下终于知道有JSONP这个东东,然后知道jsonp的格式原来就是一个callback函数名称xxx(请求中带有callback=xxx)包着一个json数据的方法的形式。其实JSONP只是用来跨域通信用的,虽然现在的需求不需要用jsonp,不过某同学没有研究出来js里面怎么直接获得同一域JSON数据,所以我还是折腾了一下。挺好,又学到些东西:P
直接上代码:如果使用的是default_app,则直接把下面代码贴进对应的py文件中就ok了
from bottle import response, request, install
def jsonp(callback):
def wrapper(*args, **kwargs):
resp = callback(*args, **kwargs)
if isinstance(resp, (dict,list)):
#response.charset='utf-8' # set property error , do not know why
response.content_type = 'application/json;utf-8' # after added this line, we do not need to mess with character encoding in json.dumps; the commented out code is what i did before
callback_arg = request.query.get('callback')
if callback_arg:
resp= '{}({})'.format(callback_arg, json.dumps(resp))#,ensure_ascii=False))#.encode('utf-8')
return resp
return wrapper
install(jsonp) # install the plugin in the bottle app
另外就是发现,处理jsonp为这样的字符串以后,返回的结果数据的中文直接显示为unicode的字符串形式(\uxxxx形式)。解决方法:
- 最开始我是让json模块dumps处理的字符串进行解码,然后encode成utf-8,这样输出就正常了(代码见被注释掉的倒数第五行)
- 后来发现只需要对返回的内容格式content-type限定为json和utf-8,就自动解析正常了(代码见倒数第八行)