Flask:浏览器(或代理)发送了该服务器无法理解的请求
Flask: The browser (or proxy) sent a request that this server could not understand
我创建了一个小型 Flask
服务。但是,每次我尝试使用 say-hi
端点时,我都会收到以下消息:
{
"message": "The browser (or proxy) sent a request that this server could not understand."
}
我的 Flask 服务如下所示:
from flask import Flask, request
from flask_restful import Resource, Api, abort, reqparse
app = Flask(__name__)
api = Api(app)
class HelloResource(Resource):
def get(self):
return { 'message': 'Hello' }
class SayHiResource(Resource):
def get(self):
parser = reqparse.RequestParser()
parser.add_argument('name', required=True, help='Name cannot be blank')
args = parser.parse_args()
return { 'message': 'Hello ' + args['name'] }
api.add_resource(HelloResource, '/hello')
api.add_resource(SayHiResource, '/say-hi')
if __name__ == '__main__':
app.run(debug=True, load_dotenv=True)
但是,关于失败原因的信息不多。
我 运行 的方式是使用 gunicorn
和 serviceEntrypoint.py
文件,
只有这个内容:
from src.api.service import app
if __name__ == '__main__':
app.run()
这是我的文件夹结构
.
├── requirements.txt
├── serviceEntrypoint.py
└── src
├── __init__.py
└── api
├── __init__.py
└── service.py
为什么 /hello
结尾有效,但当我调用 http://localhost:8000/say-hi?name=John
时 say-hi
却无效?
如果您 运行 Flask 调试服务器并发出您的 HTTP 请求 http://localhost:8000/say-hi?name=John
,您将看到实际错误是:
message "Did not attempt to load JSON data because the request Content-Type was not 'application/json'."
有文档和示例 here,但归结为选择请求应该是 GET 还是 POST。您构建请求的方式 - 您仅传递 1 个字段,用户名 - 它看起来像一个 GET,在这种情况下您应该:
api.add_resource(SayHiResource, '/say-hi/<username>')
和class:
class SayHiResource(Resource):
def get(self, username):
return { 'message': 'Hello ' + username }
如果您想实现 POST 请求,请在文档中跟踪调用触发的示例:curl http://localhost:5000/todos -d "task=something new" -X POST -v
更新:
使用查询参数,可以使用request.args
:
api.add_resource(SayHiResource, '/say-hi')
class:
class SayHiResource(Resource):
def get(self):
username = request.args.get("username")
status = request.args.get("status")
# print(query_args)
return { 'message': 'Hello {}, your status is: {}'.format(username, status) }
示例:
[http_offline@greenhat-35 /tmp/] > curl 'http://localhost:8000/say-hi?username=lala&status=enabled'
{
"message": "Hello lala, your status is: enabled"
}
[http_offline@greenhat-35 /tmp/] >
解决方法是添加location='args'
,这样reqparse只使用查询字符串值:
parser.add_argument('name', required=True, help='Name cannot be blank', location='args')
问题的原因是 Argument
has 'json' as the default location and recent versions of Werkzeug (used by flask) will raise an exception when reqparse tries to read json data from the (non-json) request. This should probably be considered a bug in reqparse, but it's deprecated,所以不要指望更新。
我创建了一个小型 Flask
服务。但是,每次我尝试使用 say-hi
端点时,我都会收到以下消息:
{
"message": "The browser (or proxy) sent a request that this server could not understand."
}
我的 Flask 服务如下所示:
from flask import Flask, request
from flask_restful import Resource, Api, abort, reqparse
app = Flask(__name__)
api = Api(app)
class HelloResource(Resource):
def get(self):
return { 'message': 'Hello' }
class SayHiResource(Resource):
def get(self):
parser = reqparse.RequestParser()
parser.add_argument('name', required=True, help='Name cannot be blank')
args = parser.parse_args()
return { 'message': 'Hello ' + args['name'] }
api.add_resource(HelloResource, '/hello')
api.add_resource(SayHiResource, '/say-hi')
if __name__ == '__main__':
app.run(debug=True, load_dotenv=True)
但是,关于失败原因的信息不多。
我 运行 的方式是使用 gunicorn
和 serviceEntrypoint.py
文件,
只有这个内容:
from src.api.service import app
if __name__ == '__main__':
app.run()
这是我的文件夹结构
.
├── requirements.txt
├── serviceEntrypoint.py
└── src
├── __init__.py
└── api
├── __init__.py
└── service.py
为什么 /hello
结尾有效,但当我调用 http://localhost:8000/say-hi?name=John
时 say-hi
却无效?
如果您 运行 Flask 调试服务器并发出您的 HTTP 请求 http://localhost:8000/say-hi?name=John
,您将看到实际错误是:
message "Did not attempt to load JSON data because the request Content-Type was not 'application/json'."
有文档和示例 here,但归结为选择请求应该是 GET 还是 POST。您构建请求的方式 - 您仅传递 1 个字段,用户名 - 它看起来像一个 GET,在这种情况下您应该:
api.add_resource(SayHiResource, '/say-hi/<username>')
和class:
class SayHiResource(Resource):
def get(self, username):
return { 'message': 'Hello ' + username }
如果您想实现 POST 请求,请在文档中跟踪调用触发的示例:curl http://localhost:5000/todos -d "task=something new" -X POST -v
更新:
使用查询参数,可以使用request.args
:
api.add_resource(SayHiResource, '/say-hi')
class:
class SayHiResource(Resource):
def get(self):
username = request.args.get("username")
status = request.args.get("status")
# print(query_args)
return { 'message': 'Hello {}, your status is: {}'.format(username, status) }
示例:
[http_offline@greenhat-35 /tmp/] > curl 'http://localhost:8000/say-hi?username=lala&status=enabled'
{
"message": "Hello lala, your status is: enabled"
}
[http_offline@greenhat-35 /tmp/] >
解决方法是添加location='args'
,这样reqparse只使用查询字符串值:
parser.add_argument('name', required=True, help='Name cannot be blank', location='args')
问题的原因是 Argument
has 'json' as the default location and recent versions of Werkzeug (used by flask) will raise an exception when reqparse tries to read json data from the (non-json) request. This should probably be considered a bug in reqparse, but it's deprecated,所以不要指望更新。