Flask-JSGlue 库简介

今天介绍一个有用的胶水库,Flask-JSGlue,看它的名字,也基本可以看出是连接 Flask 和 JavaScript 的桥梁。 我们先来看看它主要解决的问题

问题

使用 Flask 做 web 开发,不可避免的会遇到在 js 中处理 URL,而我们都知道,在 Flask 中使用 url_for 是很好的动态创建 url 的方式。举个栗子

在 HTML 中使用

1
<img src="{{ url_for('static', filename='chat/images/hi.jpg')}}">

在 后台逻辑中使用

1
return redirect(url_for('main.index'))

以上,都不会有什么问题。

问题场景

在页面加载完成之后,某些动作,会触发页面新增一些 HTML 代码,说起来比较抽象,还是看个栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function sendMessage(event, from_name, to_uid, to_uname){
var msg = $("#message_not").val();
var myDate = new Date();
var myTime = myDate.toLocaleTimeString();
var itTime = myDate.toLocaleString();
var htmlData = '<div class="msg_item fn-clear">'
+ ' <div class="uface"><img src="{{ url_for('static', filename='chat/images/hi.jpg')}}" width="40" height="40" alt=""/></div>'
+ ' <div class="item_right">'
+ ' <div class="msg own">' + msg + '</div>'
+ ' <div class="name_time">' + from_name + ' · ' + itTime +'</div>'
+ ' </div>'
+ '</div>';
$("#message_box").append(htmlData);
$('#message_box').scrollTop($("#message_box")[0].scrollHeight + 20);
$("#message_not").val('');
setTimeout(function(){sendToServernoLogin(from_name, msg)}, 1000); //延时调用
}

这是我一个在线聊天室的 js 代码,在调用该函数后,会在 message_box 中增加一段 HTML 代码,用来展示用户发送的消息。

可以看到,在 htmlData 中,对于 img 标签,我用到了 url_for 函数来动态产生 URL,因为这个是用户的头像,很显然每个用户头像会有所不同,所以动态产生 URL 就是必须的了。

这样看起来还好,直接使用 url_for 编码到 HTML 代码中,也是可行的,下面我们再来看看另一种情况。

有一个类似如下形式的函数

1
2
@app.route('/nvshen/<id>/', methods=['GET', 'POST'])
def nvshen(id):

那么使用 url_for 函数就需要为如下形式

1
url_for("nvshen", id=123)

下面再来看看如果也是需要写到 HTML 代码里呢

1
2
3
4
5
6
7
8
9
10
var myid = mydata[i][2];
var htmlText = '<article class="white-panel">' +
'<img data-original=' + myurl +' class="thumb">' +
'<h1>' +
'<a href="{{ url_for('nvshen', id=myid)}}" title="去投票" target="_blank">' +
myname + '</a>' +
'</h1>' +
'<p>' +
'</p>' +
'</article>';

类似上面的写法,我试过了各种方式,都不能正确传递 myid 的值,如果有哪位小伙伴知道解法的话,还请告知下。

使用 Flask-JSGlue 解决

我们先来看看 Flask-JSGlue 的官网,上面的例子也是非常的简单

后台逻辑

1
2
3
4
5
from flask import Flask
from flask_jsglue import JSGlue

app = Flask(__name__)
jsglue = JSGlue(app)

前端页面

1
2
3
4
5
6
7
8
9
<head>{{ JSGlue.include() }}</head>

Flask.url_for("index")

Flask.url_for("static", {"filename": "jquery.min.js"})

Flask.url_for("api.hello_world", {"param1": 1, "param2": "text"})

Flask.url_for("api.external_link", {"_external": true, "_scheme": "https", "_anchor": "main"})

对于需要传递 url 参数的情况,也能够很好的支持,beautiful!

改写上面的 HTML 字符串

1
'<a href=URL title="去投票" target="_blank">'.replace("URL", Flask.url_for("nvshen", {id: myid})) +

完美解决

反正我是被惊艳到了,终于解决了我长久以来的困扰,香!

感觉本站内容不错,有收获?