Flask REST-API大整数返回值错误问题排查与解决求助
问题分析与解决:Flask-RESTx返回大整数精度丢失
问题原因
- JavaScript的
Number类型基于双精度浮点数,仅能精确表示2^53(即9007199254740992)以内的整数。你的目标数值6195659448464973308远超出该阈值,当JSON中的数字类型被JS解析时,会因浮点数精度限制被近似处理,导致末尾数位丢失。 - Flask-RESTx默认将Python整数序列化为JSON的数字类型,而JSON本身没有原生大整数类型,无法在不丢失精度的前提下将超大整数传输至JS环境。
解决方法
方案1:将大整数转为字符串返回
这是最直接的方案,通过将整数转为字符串,JSON会以字符串类型存储数值,前端接收后可完整保留精度,需要时再转换为BigInt处理:
from flask_restx import Resource, Namespace ns = Namespace('resources') @ns.route('/<id_>') @ns.doc(params={"id_": "ID of a resource"}) class ResourceItem(Resource): @staticmethod @ns.doc(responses={200: "Success", 404: "Not found"}) def get(id_): # 单个值返回字符串 return str(6195659448464973308), 200 # 返回JSON对象时同样转字符串 # return {"value": str(6195659448464973308)}, 200
方案2:自定义JSON编码器适配JS的BigInt
如果前端使用JavaScript,可以自定义序列化逻辑,将超大整数转为BigInt()格式的字符串,前端可直接解析为原生BigInt类型:
from flask_restx import Resource, Namespace from flask.json import JSONEncoder class BigIntJSONEncoder(JSONEncoder): def default(self, obj): # 2^53是JS Number的精确整数上限 if isinstance(obj, int) and obj > 2**53: return f"BigInt({obj})" return super().default(obj) # 为当前namespace设置自定义编码器 ns = Namespace('resources') ns.api.json_encoder = BigIntJSONEncoder @ns.route('/<id_>') @ns.doc(params={"id_": "ID of a resource"}) class ResourceItem(Resource): @staticmethod @ns.doc(responses={200: "Success", 404: "Not found"}) def get(id_): return {"value": 6195659448464973308}, 200
前端解析示例(安全方式,避免eval):
const numStr = response.data.value.replace(/^BigInt\((\d+)\)$/, '$1'); const bigIntValue = BigInt(numStr);
方案3:使用simplejson自动序列化大整数为字符串
借助simplejson库的bigint_as_string参数,可自动将超出JS精度的整数转为字符串,无需手动修改代码:
from flask_restx import Resource, Namespace import simplejson as json ns = Namespace('resources') @ns.route('/<id_>') @ns.doc(params={"id_": "ID of a resource"}) class ResourceItem(Resource): @staticmethod @ns.doc(responses={200: "Success", 404: "Not found"}) def get(id_): data = {"value": 6195659448464973308} response = ns.api.make_response( json.dumps(data, bigint_as_string=True), 200 ) response.headers['Content-Type'] = 'application/json' return response
内容的提问来源于stack exchange,提问作者Jakob
相关产品推荐
相关产品推荐

