关于Todoism: login 回调函数不执行


问题描述:点击Get a test account后产生账号密码,然后点击Login按钮,没有任何反应
源码调试:发现auth.login正确执行,但js中login_user中的回调函数好像没执行

@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
    print('login:begin!')
    if current_user.is_authenticated:
        print('Run:authenticated here!')
        return redirect(url_for('todo.app'))

    if request.method == 'POST':
        print('POST:here!')
        data = request.get_json()
        username = data['username']
        password = data['password']

        user = User.query.filter_by(username=username).first()

        if user is not None and user.validate_password(password):
            login_user(user)
            print('login_user Success!')
            return jsonify(message=_('Login success.'))
        return jsonify(message=_('Invalid username or password.')), 400
    return render_template('_login.html')

后台运行:

 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [22/Mar/2019 19:51:56] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [22/Mar/2019 19:51:56] "GET /intro HTTP/1.1" 200 -
login:begin!
127.0.0.1 - - [22/Mar/2019 19:51:58] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [22/Mar/2019 19:52:02] "GET /register HTTP/1.1" 200 -
login:begin!
POST:here!
login_user Success!
127.0.0.1 - - [22/Mar/2019 19:52:04] "POST /login HTTP/1.1" 200 -

js源码:

    function login_user(){
        var username = $('#username-input').val();
        var password = $('#password-input').val();

        if(!username || !password) {
            M.toast({html: login_error_message});
            return;
        }

        var data = {
            'username': username,
            'password': password
        };

        $.ajax({
            type: 'POST',
            url: login_url,
            data: JSON.stringify(data),
            contentType: 'application/json;charset=UTF-8',
            success: function (data) {
                if (window.location.hash === '#app' || window.lacation.hash === 'app'){
                    $(window).trigger('hashchange');
                } else {
                    window.location.hash = '#app';
                }
                activeM();
                M.toast({html: data.message, displayLength: 1000});
            }
        });
    }

请各位指教!

建议先通过下面的方式自行检查:

  • 使用文本对比工具和示例程序源码进行对比。
  • 修正 success 回调里的拼写错误:lacation。
  • 查看浏览器开发者工具控制台有没有错误输出。

另外,下次发帖请正确设置分类。

李老师:问题不出在文本上(已对比改了),因为运行你的源码也存在同样的问题,
控制台调试如下所示:

 * Serving Flask app "mytodoism" (lazy loading)
 * Environment: development
 * Debug mode: on
 * Restarting with windowsapi reloader
 * Debugger is active!
 * Debugger PIN: 276-122-974
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [22/Mar/2019 21:41:56] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [22/Mar/2019 21:41:56] "GET /intro HTTP/1.1" 200 -
login:begin!
127.0.0.1 - - [22/Mar/2019 21:41:59] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [22/Mar/2019 21:42:01] "GET /register HTTP/1.1" 200 -
login:begin!
POST:here!
127.0.0.1 - - [22/Mar/2019 21:42:03] "POST /login HTTP/1.1" 200 -
login_user Success!

你试试运行示例程序 Demo 会不会出现这个问题?

线上demo不存在问题,本地运行存在此问题

好的,我明天抽空在本地试一下。另外可以试下清除浏览器缓存。

我从仓库clone的代码没有出现这个问题,同样建议清除浏览器缓存。
另外我想问一下,回调函数中先判断hash是否等于#app是为什么啊?感觉登录的时候不会在这个hash网址啊…

本地测试没有问题。

@Arvine 比如你保存了程序主页的书签(书签的 hash 为 #app),某天登录过期会自动转到登录页面,这时页面的 hash 就是 #app。你可以试试在未登录的状态下访问 http://todoism.helloflask.com/#app

在QQ浏览器能稳定运行,在360浏览器存在这个问题,不知何因?
另外:

            success: function (data) {
                if (window.location.hash === '#app' || window.location.hash === 'app') {
                    $(window).trigger('hashchange');
                } else {
                window.location.hash = '#app';
                }
                activeM();
                M.toast({html: data.message, displayLength: 1000});
            }

这个回调函数直接改成如下:效果不是一样吗?

            success: function (data) {
                window.location.hash = '#app';  # 赋值后马上触发hashchange事件                
                activeM();
                M.toast({html: data.message, displayLength: 1000});
            }

有什么不同?

你可以在本地试一下这样的操作:

还有个问题:点击Get a account后,在输入框直接按回车没捕获keyup事件(没反应),也就是以下这段好像无效:

    $('.login_input').on('keyup', function(e){
        if (e.which === ENTER_KEY){
            login_user();
        }
    });
1 个赞

了解了 谢谢!

我这里也是无效的,改成下面这样的话可以

$(document).on('keyup', '.login-input', function (e) {
       if (e.which === ENTER_KEY) {
           login_user();
       }
    });
1 个赞

这个是 bug,已经在 master 分支修复。

还想问一下…为什么原来的写法会没有反应啊?感觉也没写错啊

是啊,真有点怀疑Query的健壮性了!相同的程序,不同的浏览器有不同的执行!现在又碰到一个问题,
点击编辑条目,原内容变清空了,线上demo正常,QQ、360浏览器都清空了,不知咋回事?

    $(document).on('click', '.edit-btn', function () {
        var $item = $(this).parent().parent();
        var itemId = $item.data('id');
        var itemBody = $('#body' + itemId).text();
        $item.hide();
        $item.after(' \
                <div class="row card-panel hoverable">\
                <input class="validate" id="edit-item-input" type="text" value="' + itemBody + '"\
                autocomplete="off" autofocus required> \
                </div> \
            ');

        var $edit_input = $('#edit-item-input');
        var strLength = $edit_input.val().length * 2;

        $edit_input.focus();
        $edit_input[0].setSelectionRange(strLength, strLength);

        $(document).on('keydown', function (e) {
            if (e.keyCode === ESC_KEY) {
                remove_edit_input();
            }
        });
···

on() 虽然可以将事件绑定到动态增加的元素,但是前提是目标需要为动态增加的子元素,所以需要监听 login-input 的父元素。

感谢反馈,新的问题创建新主题吧,不要追加新问题。