Python bottle support for JSONP

最近用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,就自动解析正常了(代码见倒数第八行)