Flask 继学习 之 py与js文件的关系和通信

时间:2024-03-23 18:51:33

py文件是如何和js文件互动的?

在Python和JavaScript之间实现互动通常需要使用一些特定的工具或技术。以下是一种常见的方法:

  1. 使用Web框架:可以使用Python的Web框架(如Django、Flask等)来创建一个Web应用程序。在这种情况下,你可以将Python代码和JavaScript代码嵌入到HTML文件中,并通过HTTP请求进行通信。

  2. 使用AJAX:AJAX(Asynchronous JavaScript and XML)是一种在不重新加载整个页面的情况下与服务器进行异步通信的技术。你可以使用JavaScript中的AJAX方法(如XMLHttpRequest或fetch)向服务器发送HTTP请求,并接收来自服务器的响应response服务器端可以使用Python来处理这些请求,并return返回相应的数据。

  3. 使用WebSocket:WebSocket是一种在客户端和服务器之间实现双向通信的协议。你可以使用JavaScript中的WebSocket API与服务器建立WebSocket连接,并通过该连接发送和接收数据。在服务器端,你可以使用Python的WebSocket库(如Tornado、Flask-SocketIO等)来处理WebSocket连接和消息。

  4. 使用RPC(远程过程调用):RPC是一种允许不同进程或计算机之间进行通信的技术。你可以使用Python中的RPC库(如Pyro4、xmlrpc等)来创建一个RPC服务器,并使用JavaScript中的RPC库(如JSON-RPC、gRPC-web等)来调用该服务器上的方法。

login.html

{% extends "common/layout_user.html" %}
{% block content %}
<div class="loginColumns animated fadeInDown">
	<div class="row">

		<div class="col-md-6 text-center">
			<h2 class="font-bold">{{ config.SEO_TITLE }}</h2>
			<p>
				<img src="{{ buildStaticUrl('/images/common/mini_qrcode.jpg') }}" width="300px">
			</p>

		</div>
		<div class="col-md-6">
			<div class="ibox-content">
				<div class="m-t login_wrap" >
                    <div class="form-group text-center">
                        <h2 class="font-bold">登录</h2>
                    </div>
					<div class="form-group">
						<input type="text" name="login_name" class="form-control" placeholder="请输入登录用户名">
					</div>
					<div class="form-group">
						<input type="password" name="login_pwd" class="form-control" placeholder="请输入登录密码">
					</div>
					<button type="button" class="btn btn-primary block full-width m-b do-login">登录</button>
                <h3>账号和密码请联系公司管理员</h3>
			</div>
		</div>
	</div>
    </div>
	<hr>
	<div class="row">
		<div class="col-md-6">
            {{ config.SEO_TITLE }} <a href="{{ buildUrl('/') }}" target="_blank"> 技术支持 </a>
		</div>
		<div class="col-md-6 text-right">
			<small>© 2024</small>
		</div>
	</div>
</div>

{% endblock %}

{% block js %}
    <script src="{{ buildStaticUrl('/js/user/login.js') }}"></script>
{% endblock %}

user.py
 

route_user = Blueprint('user_page', __name__)

@route_user.route('/login', methods = ['GET', 'POST'])
# 这段代码是一个用户登录的处理函数
def login():
    if request.method =="GET":
        # 当请求方法为GET时,如果用户已经登录,则重定向到首页
        if g.current_user:
            return redirect( UrlManager.buildUrl("/index/"),)
        # 否则渲染登录页面
        return render_template("user/login.html")
    # 当请求方法为POST时,获取登录名和密码,并查询数据库中是否存在对应的用户信息。
    resp = {'code': 200, 'msg': '登录成功~~', 'data': {}}
    req = request.values
    login_name = req['login_name'] if 'login_name' in req else ''
    login_pwd = req['login_pwd'] if 'login_pwd' in req else ''
    # 如果存在,则返回登录成功的消息,并设置一个名为AUTH_COOKIE_NAME的cookie,保存用户的认证信息和用户ID,有效期为120天
    if login_name is None or len( login_name ) < 1:
        resp['code'] = -1
        resp['msg'] = "请输入正确的登录用户名~~"
        return jsonify(resp)

    if login_pwd is None or len(login_name) < 1:
        resp['code'] = -1
        resp['msg'] = "请输入正确的密码~~"
        return jsonify(resp)

    user_info = User.query.filter_by( login_name = login_name ).first()

    if not user_info:
        resp['code'] = -1
        resp['msg'] = '请输入正确的登录用户名和密码-1~~'
        return jsonify(resp)

    if user_info.login_pwd != UserService.genePwd( login_pwd, user_info.login_salt ):
        resp['code'] = -2
        resp['msg'] = '请输入正确的登录用户名和密码-2~~'
        return jsonify(resp)

    if user_info.status !=1:
        resp['code'] = -3
        resp['msg'] = '账号已被禁用,请联系管理员处理~~'
        return jsonify(resp)

    # 设置相应
    # # make_response()函数的作用是创建一个包含指定内容的响应对象。它可以将字符串、字典、元组或者响应对象转换为一个响应对象。
    response = make_response(json.dumps({'code':200, 'msg':'登录成功~~'}))
    # # json.dumps()函数的作用是将Python对象转换为JSON格式的字符串。它可以将字典、列表等Python对象转换为JSON字符串,以便在网络传输或存储时使用。

    #  设置cookie
    response.set_cookie( app.config['AUTH_COOKIE_NAME'], '%s#%s' % (
        UserService.geneAuthCode(user_info), user_info.uid), 60 * 60 * 24 * 120)   # 保存120填
    # 最后返回一个包含登录成功消息的JSON响应。
    return response

#
# set_cookie()函数用于设置响应对象的cookie。它接受多个参数,其中包括cookie的名称、值、过期时间等。
# 通过调用set_cookie()函数,可以将cookie添加到响应对象中,并在客户端保存。

login.js

;
var user_login_ops = {
    init:function(){
        this.eventBind();
    },
    eventBind:function(){
        $(".login_wrap .do-login").click( function(){
            var btn_target = $(this);
            if( btn_target.hasClass("disabled") ){
                common_ops.alert("正在处理!!请不要重复提交~~");
                return;
            }

            var login_name = $(".login_wrap input[name=login_name]").val();
            var login_pwd = $(".login_wrap input[name=login_pwd]").val();


            if( login_name == undefined || login_name.length < 1){
                common_ops.alert( "请输入正确的登录用户名~~" );
                return;
            }
            if( login_pwd == undefined || login_pwd.length < 1){
                common_ops.alert( "请输入正确的密码~~" );
                return;
            }
            btn_target.addClass("disabled");
            $.ajax({
                url:common_ops.buildUrl("/user/login"),
                type:'POST',
                data:{ 'login_name':login_name,'login_pwd':login_pwd },
                dataType:'json',
                success:function(res){
                    btn_target.removeClass("disabled");
                    var callback = null;
                    if( res.code == 200 ){
                        callback = function(){
                            window.location.href = common_ops.buildUrl("/index");
                        }
                    }
                    common_ops.alert( res.msg,callback );
                }
            });
        } );
    }
};

$(document).ready( function(){
    user_login_ops.init();
} );

问题: 如果将服务器端的return response 改为return redirect('index.html'),则在实际网页登录框中按钮点下去后没反应,再点就会提示相应提示“正在处理!!请不要重复提交~~”

这是因为html的页面已经和js做好了功能绑定和关联,在js文件中定义了按钮的相关设置,因为在服务器端删除了要发给js的信号--response,所以js因为迟迟收不到服务器返回来的response,一致处于按钮disable停滞状态。

如此看来,html   js  以及 py 文件都是起着微妙微翘、相互关联、相互传导信息的作用的。

py 给js文件的reponse对象一般都是什么格式的?案例分析一下:

在Python中,将响应对象转换为JavaScript文件时,通常使用JSON格式。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,并且在不同编程语言之间具有良好的兼容性。

以下是一个示例,展示了将Python中的响应对象转换为JSON格式的JavaScript文件:

import json

# 假设response是一个包含数据的响应对象
response = {
    "status": 200,
    "message": "Success",
    "data": {
        "name": "John",
        "age": 25,
        "city": "New York"
    }
}

# 将响应对象转换为JSON格式的字符串
json_response = json.dumps(response)

# 将JSON字符串写入JavaScript文件
with open("response.js", "w") as file:
    file.write(f"var response = {json_response};")

在上述示例中,我们使用了Python内置的json模块将响应对象response转换为JSON格式的字符串json_response。然后,我们将该字符串写入名为response.js的JavaScript文件中,并将其赋值给JavaScript变量response

问题:json格式是什么样子的?

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于前后端数据传输和存储。它以键值对的形式组织数据,并使用大括号({})表示对象,方括号([])表示数组。

JSON对象由多个键值对组成,每个键值对之间使用逗号(,)分隔。键是一个字符串,值可以是字符串、数字、布尔值、对象、数组或null。键和值之间使用冒号(:)分隔。

以下是一个JSON对象的示例:

{
  "name": "John",
  "age": 30,
  "isStudent": false,
  "address": {
    "street": "123 Main St",
    "city": "New York"
  },
  "hobbies": ["reading", "traveling", "photography"]
}

在上面的示例中,有几个键值对:

  • “name”: “John” 表示名字是"John"
  • “age”: 30 表示年龄是30
  • “isStudent”: false 表示是否是学生为false
  • “address”: {…} 表示地址是一个嵌套的JSON对象
  • “hobbies”: […] 表示爱好是一个包含多个元素的数组