Method Not Allowed- The method is not allowed for the requested URL

文章目录

  • 现象
  • 分析
    • 密码重置流程如下:
    • 代码如下
    • log分析
  • 解决方法
  • 总结

现象

在用flask实现一个密码重置功能时,遇到如下问题:
report: 
Method Not Allowed The method is not allowed for the requested URL.

分析

密码重置流程如下:

1)登录界面放置重置密码超链接,指向/auth/start_resetpwd
2)/auth/start_resetpwd渲染start_resetpwd.html界面(提示用户输入注册邮箱,和"下一步"按钮),用户输入注册邮箱,点击"下一步"按钮后,系统向用户的注册邮箱发送一个连接(形如/auth/resetpwd/),提示用户查看邮箱,使用邮件中的连接进入下一步
3)/auth/resetpwd/响应:检查token是否有效,如果有效,则渲染“/auth/resetpwd.html”。“/auth/resetpwd/html”界面,要求用户输入两遍新密码,然后点击“确认”按钮。当点击“确认”按钮后,便弹出如下信息:
report: 
Method Not Allowed The method is not allowed for the requested URL.

代码如下

@auth.route('/resetpwd/')
def resetpassword_checktoken(token):
    email = session.get('email')
    if email:
        user = User.query.filter_by(email=email).first()
        if user and user.check_resetpwd_token(token):
            form = ResetpasswordForm()
            return render_template('auth/resetpwd.html', form=form)//pos A
        flash('Email %s has not been registered or the token has been expired!' % (email))
    return redirect(url_for('auth.login'))

@auth.route('/resetpwd', methods=['GET', 'POST'])
def resetpwd():
    form = ResetpasswordForm()
    email = session.get('email')
    user = User.query.filter_by(email=email).first()
    logger.info('resetpwd user %s' % user.username)//pos B
    if user and form.validate_on_submit():
        user.password = form.password.data
        db.session.add(user)
        logger.info('resetpwd user2 %s' % user.username)//pos C
        db.session.commit()
        logger.info('resetpwd user3 %s' % user.username)
        logger.flush()
        return redirect(url_for('auth.login'))
    logger.info('resetpwd user4 %s' % user.username)
    return render_template('auth/resetpwd.html', form=form)

log分析

log信息如下:

INFO:werkzeug:127.0.0.1 - - [15/Aug/2019 09:06:30] "GET /auth/resetpassword HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [15/Aug/2019 09:06:36] "POST /auth/resetpassword HTTP/1.1" 302 -
INFO:werkzeug:127.0.0.1 - - [15/Aug/2019 09:06:36] "GET /auth/login HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [15/Aug/2019 09:06:49] "GET /auth/resetpwd/eyJhbGciOiJIUzUxMiIsImlhdCI6MTU2NTgzMTE5NiwiZXhwIjoxNTY1ODMxNzk2fQ.eyJyZXNldHB3ZCI6MX0.xd9hzjI7lbfE16WkeeMMKUiz7nS6GHT7wos-W9lFnl3V7mReDDjf3wX_eR4giZzs_YJj03v7AvOaVMF8G-SKgQ HTTP/1.1" 200 -
INFO:werkzeug:127.0.0.1 - - [15/Aug/2019 09:07:43] "POST /auth/resetpwd/eyJhbGciOiJIUzUxMiIsImlhdCI6MTU2NTgzMTE5NiwiZXhwIjoxNTY1ODMxNzk2fQ.eyJyZXNldHB3ZCI6MX0.xd9hzjI7lbfE16WkeeMMKUiz7nS6GHT7wos-W9lFnl3V7mReDDjf3wX_eR4giZzs_YJj03v7AvOaVMF8G-SKgQ HTTP/1.1" 405 -

有如下问题:
1)当运行万pos A后,期望打印pos B,但是B没有打印
2)点击“确认”后,期望打印pos C,但是C没有打印
3)根据werkzeug的log信息可以看到 /auth/resetpwd/的GET响应后,调用/auth/resetpwd/的POST的处理。期望是:/auth/resetpwd/的GET -> /auth/resetpwd GET -> /auth/resetpwd POST
所以问题出在token检查无误后,应用重定向到/auth/resetpwd下。

解决方法

代码如下:

@auth.route('/resetpwd/')
def resetpassword_checktoken(token):
    email = session.get('email')
    if email:
        user = User.query.filter_by(email=email).first()
        if user and user.check_resetpwd_token(token):
            redirect(url_for('auth.resetpwd'))
        flash('Email %s has not been registered or the token has been expired!' % (email))
    return redirect(url_for('auth.login'))

总结

对于出现
Method Not AllowedThe method is not allowed for the requested URL.
一般是因为URL响应不支持一定的操作,比如POST。所以处理方法是

@auth.route('/resetpwd/', methods=['GET', 'POST'])
def resetpassword_checktoken(token):

但这次的问题是,URL响应划分不合理,启用新界面后,良好的做法是为新界面启用一个新的URL(当然,方法不唯一。选择自己喜欢的方式就行)。

你可能感兴趣的:(python,python)