文档章节

总结一下flask和ajax之间的json、jsonp通讯

Klaus88
 Klaus88
发布于 2014/12/22 15:37
字数 1073
阅读 1701
收藏 2

最近有点忙,flask开始用于生产中了,在这个json为主的微服务架构的天下,flask确实很得心应手。

下面总结一下最近的实践吧,分几个部分来写。

1、ajax发送和接收flask的json和值

2、flask接收ajax的json和值

3、flask返回json和值

下面开始:


1、ajax发送和接收flask的json和值

最方便就是用jquery了。之前试过用原生的方法,都是有的问题,特别是jsonp,更是麻烦。

所以,乖乖用jquery吧。

引用jquery很简单嘛,<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>

//get传值,获取jsonp    
$.ajax({
        url: "http://127.0.0.1:5000/main/get_json/999",
        dataType: "jsonp",
        jsonp: "callback",
        success: function (data) {
            alert(data.hits);
        }
    })

这个是用jqery的ajax最原生的方式,最大的好处就是可以设置超时后的回调事件,这里没写出来。

这个是获取jsonp的方式,如果是获得json,也是一样的,更简单,去掉相应的dataType和jsonp就行了。

data是返回的json,取值的话就取相应的字段,hits这样的。

post传递json,返回获取json

//post传递json,返回获取json

//创建传递的参数
var postdata = {
    ID: 1
};
$.post("http://127.0.0.1:5000/main/post_json/", postdata, function (data) {
    if (data.ret == "OK") {
        alert("成功!");
    }
    else {
        alert("失败,原因:" + data.ret);
    }
}


ajax基本上有很多资料了,都不难。下面是重点,flask方的。

2、flask接收ajax的json和值

接收get的值我实践过了,很简单,也就是一般的request.args.get。

接收post过来的json没试过,看资料是这样的

@app.route('/json', methods=['POST'])
def my_json():  
    print request.headers
    print request.json
    rt = {'info':'hello '+request.json['name']}    
    return Response(json.dumps(rt),  mimetype='application/json')


3、flask返回json和值

先说简单的,返回一个值。

就直接return一个str回去就行了。

比如

return "100"

return str(100)


下面是最复杂的了,返回json。

A、直接返回json

这个也简单

from flask import jsonify

#返回单值
@app.route('/get_count/<unique_mark>')
def get_count(unique_mark):
    return jsonify(hits=0)

#返回list
@app.route('/get_count/<unique_mark>')
def get_count(unique_mark):
    ret=[1,2,3,4,5]
    return jsonify(ret_list=ret)

这2个是基本的用法,但是对于大部分人来说,最大的问题是怎么返回一个flask-sqlalchemy的查询结果集。

这个我研究了很久,终于折腾出了一个class,只要继承之,就搞定鸟!

下面放出那个class。

class AutoSerialize(object):
    '''
    Mixin for retrieving public fields of model in json-compatible format
    '''
    __allowed_in_json__ = None

    def get_serialize(self, exclude=()):
        '''Returns model's PUBLIC data for jsonify'''
        data = {}
        keys = self._sa_class_manager.mapper.mapped_table.columns
        public = self.__allowed_in_json__
        for col in keys:
            if public is not None:
                if col.name not in public:
                    continue
            if col.name in exclude:
                continue
            data[col.name] = self._serialize(getattr(self, col.name))
        return data

    @classmethod
    def _serialize(cls, value):
        if type(value) in (int, float, long, bool):
            ret = str(value)
        elif type(value) is unicode:
            ret = value.encode('utf-8')
        elif isinstance(value, datetime.date):
            ret = value.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(value, datetime.time) or isinstance(value, datetime.datetime):
            ret = value.isoformat()
        elif isinstance(value, decimal.Decimal):
            ret = str(value)
        else:
            ret = value

        return ret

这个class的作用其实很简单,就是序列化一个结果集。

用法是这样:

先是一个普通的model类,继承一下它:

class User(db.Model, AutoSerialize):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(25), default='')
    mobile = db.Column(db.String(20), default='')
    prize = db.Column(db.Integer, default=0)
    create_time = db.Column(db.DateTime)
    upload = db.Column(db.String(25), default='')

在就是查询出来后,要这样讲结果集转换成列表。

@bp.route('/get_prize_users/')
def get_prize_users():
    page_index = int(request.args.get('page')) or 1
    page_size = int(request.args.get('rows')) or 20

    users_count = User.query.filter_by(prize=1).count()
    users = User.query.filter_by(prize=1).order_by(User.id.desc()).paginate(page_index, page_size, False)
    return jsonify(total=users_count, rows=[u.get_serialize() for u in users.items])

重点就在这里:

rows=[u.get_serialize() for u in users.items]

话说,python写着就是爽啊那么一句话就搞定别的语言一堆的代码。

另外说一下,上面那个get_prize_users()返回的结果集,是用在easyui里的datagrid上的。

最后的一关,jsonp。

其实jsonp不神秘,但是从前面可以知道,要在ajax里用callback来调用。

所以,普通的json只要包装一下,就是jsonp了。其实包装是比较麻烦的,但是python就是牛啊,我们做一个修饰器搞定。

def support_jsonp(f):
    """Wraps JSONified output for JSONP"""

    @wraps(f)
    def decorated_function(*args, **kwargs):
        callback = request.args.get('callback', False)
        if callback:
            content = str(callback) + '(' + str(f(*args, **kwargs).data) + ')'
            return current_app.response_class(content, mimetype='application/javascript')
        else:
            return f(*args, **kwargs)

    return decorated_function

就是上面那货了,怎么用哈哈,修饰器嘛,和我们最常用的@app.route没区别。

@bp.route('/get_count/<unique_mark>')
@support_jsonp
def get_count(unique_mark):
    link = Link.get_id_by_unique_mark(unique_mark)
    if link is None:
        return jsonify(hits=0)
    else:
        return jsonify(hits=link.hits)

就是那么简单!

fin.

© 著作权归作者所有

共有 人打赏支持
Klaus88
粉丝 5
博文 15
码字总数 7457
作品 0
南宁
高级程序员
私信 提问
SegmentFault 技术周刊 Vol.33 - 什么是 JSON ?

JSON 的全称是JavaScript Object Notation,可以翻译为 JavaScript 对象表示法,即将一个 Object 以文本的方式给记录下来。 根据 ECMA-404 标准: JSON is a text format that facilitates s...

keke
2017/09/07
0
0
ajax jsonp其本质 用原生js来处理跨域的数据(jsonp)

说明总结: 1.ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。 2.但是ajax和jsonp在...

BearCatYN
2015/06/04
0
0
JSONP跨域的原理解析

JavaScript是一种在Web开发中经常使用的前端动态脚本技术。在JavaScript中,有一个很重要的安全性限制,被称为“Same-Origin Policy”(同源策略)。这一策略对于JavaScript代码能够访问的页...

武文海
2016/03/21
24
0
JSONP原理优缺点(只能GET不支持POST)

JSONP的优点是:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都 可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕...

BearCatYN
2015/06/04
0
0
说说JSON和JSONP,也许你会豁然开朗(转)

言   由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现。   当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socket通讯和本...

老朱教授
2017/08/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

《大数据白皮书(2018年)》发布(解读版+完整版PPT)

数据观微信小编获悉,为更好促进大数据与实体经济融合,研判技术发展路径,总结管理痛点、描绘发展趋势,总结行业应用渗透路径,4月18日,在“2018大数据产业峰会”上,中国信息通信研究院(...

了凡川
30分钟前
1
0
从小白到月薪上万,一份完整的大数据路线分析出自我成长书单

大数据原理与实践 大数据分三大部分,包括:大数据基础、技术原理和创新实践。 大数据基础部分主要介绍大数据的基本概念、技术架构和大数据的应用场景; 第二部分大数据技术原理主要介绍大数...

董黎明
41分钟前
2
0
斗鱼直播确定赴美IPO 此前融资额已达70亿元

据最新消息,斗鱼直播高层人士向新京报证实,斗鱼直播确定赴美IPO(首次公开募股),此前融资额已达70亿元。 此前,多家媒体报道,由国内知名直播平台斗鱼(Douyu)已秘密提交赴美IPO文件。 ...

ThinkSNS官方帐号
43分钟前
3
0
虎牙直播在微服务改造方面的实践和总结

相比文字和图片,直播提供了人与人之间更丰富的沟通形式,其对平台稳定性的考验很大,那么倡导“以技术驱动娱乐”的虎牙直播(以下简称“虎牙”)是如何在技术上赋能娱乐,本文将为您介绍虎牙...

阿里云云栖社区
46分钟前
1
0
采用SpringBoot整合Mybatis框架插入数据时报错及解决

这两天做SpringBoot整合Mybatis项目的时候,插入时报错: 3:45:59.936 DEBUG [http-nio-8080-exec-8] o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver 133 - Resolving exception from ha......

aiChuang
52分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部