Flask开发随机密码生成器出现JSONDecodeError与405错误排查
问题根因
返回405状态码、后续触发JSON解析错误是服务端路由配置、代码逻辑、客户端请求配置多处错误共同导致的,核心问题点如下:
- 路由拼写错误是405的直接诱因:服务端注册路由时写的是
'/api/ PyPassword_generator',/api/后多了一个多余空格,实际生效的路由带空格,和客户端请求的/api/PyPassword_generator路径不匹配,Flask找不到对应接口就返回405的HTML错误页,客户端拿HTML内容调用.json()方法自然会触发JSON解码失败。 - 服务端监听配置和客户端请求地址不匹配:服务端启动时监听的是
10.0.0.10:5000,客户端发请求的目标地址是127.0.0.1:1337,即便路由正确也无法正常连通。 - 代码结构错误:密码生成的逻辑块缩进错误,被写到了
run()方法内部,接口里调用的self.test(a,b,c)方法根本不存在,密码生成逻辑没有被定义为可调用的类方法。 - 接口返回值缺失:接口内调用
jsonify()生成响应后没有加return关键字,逻辑跑通也无法给客户端返回正确的JSON数据。 - HTTP方法写法不规范:路由的methods参数里写的是
'Get',Flask要求HTTP方法名必须全大写,正确写法为'GET'。 - 传参顺序错误:实例化服务端类时,第二个位置传的是数字列表、第三个位置传的是符号列表,和类初始化方法接收的
symbols、numbers参数顺序相反,会导致生成的密码字符类型不符合预期。 - 客户端判断逻辑错误:
if r: break的判断逻辑完全写反,requests库中只要服务端返回响应(哪怕是4xx/5xx错误),响应对象的布尔值都是True,会直接跳出循环,根本走不到后续响应解析的步骤。
修复方案
1. 修正后的服务端代码
from flask import Flask, request, jsonify import random class game: def __init__(self,letters,symbols,numbers): self.letters=letters self.symbols=symbols self.numbers=numbers self.app = Flask("Shmuel Api server",static_url_path='') self.app.secret_key="Secret" # 去掉路由多余空格,HTTP方法改为全大写 @self.app.route('/api/PyPassword_generator', methods=['GET',"POST"]) def PyPassword_generator(): a=int(request.json["letters"]) b=int(request.json["symbols"]) c=int(request.json["numbers"]) password = self.generate_pwd(a,b,c) # 补充return关键字返回JSON响应 return jsonify({"password": password}) # 把密码生成逻辑定义为独立类方法,修正缩进 def generate_pwd(self, a, b, c): password_list=[] for char in range(a): password_list.append(random.choice(self.letters)) for char in range(b): password_list.append(random.choice(self.symbols)) for char in range(c): password_list.append(random.choice(self.numbers)) random.shuffle(password_list) password="".join(password_list) return password def run(self): # 监听地址、端口和客户端保持一致 self.app.run(host='127.0.0.1', port=1337, debug=True) # 修正传参顺序,保证字母、符号、数字和初始化参数一一对应 mp=game( ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"], ["!","#","$","%","&","(",")","*","+"], ["0","1","2","3","4","5","6","7","8","9"] ) mp.run()
2. 修正后的客户端代码
import requests import json session=requests.session() header={"content-type": "application/json"} print("Welcome to the PyPassword generator!") while True: # 输入时直接转整数,避免服务端类型转换报错 letters = int(input("how many letters would you like in your password? > ")) symbols = int(input("how many symbols would you like? > ")) numbers = int(input("how many numbers would you like? > ")) data={"letters":letters,"symbols":symbols,"numbers":numbers} print(data) r=session.post("http://127.0.0.1:1337/api/PyPassword_generator", data=json.dumps(data), headers=header) # 只有状态码为200时才解析JSON,否则打印错误信息 if r.status_code == 200: json_data=r.json() print(f"your password is : {json_data['password']}") break else: print(f"request failed, status code: {r.status_code}, err: {r.text}")
修复完成后先启动服务端,再运行客户端,输入需要的字符长度即可正常生成随机密码,不会再出现405报错和JSON解析错误。
内容的提问来源于stack exchange,提问作者Corvus123
相关产品推荐
相关产品推荐

