[关闭]
@harpsword 2015-11-04T12:44:40.000000Z 字数 3003 阅读 15135

使用flask过程中,request无法解析json类型报文

python flask bug


bug的发现

我使用的是 python2.7、flask,具体的使用过程如下

  1. from flask import Flask, request
  2. app = Flask(__name__)
  3. app.route('/api/post', methods=['POST'])
  4. def post():
  5. getForm = requst.form.get('token')

发送的报文header

  1. Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  2. Accept-Encoding:gzip, deflate, lzma, sdch
  3. Accept-Language:zh-CN,zh;q=0.8
  4. Connection:keep-alive
  5. Content-Type:application/json
  6. Host:maprun.hustonline.net
  7. Upgrade-Insecure-Requests:1
  8. User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36 OPR/33.0.1990.43

报文body

  1. '{"token":"json received"}'

但是结果报错,与 form-data、x-www-form-urlencoded 格式的报文不同。

官网的解释

class flask.Request( environ, populate_request=True, shallow=False )
The request object used by default in Flask. Remembers the matched endpoint and view arguments.

It is what ends up as request. If you want to replace the request object used you can subclass this and set request_class to your subclass.

The request object is a Request subclass and provides all of the attributes Werkzeug defines plus a few Flask specific ones.

  • form
    一个包含解析过的从 POST 或 PUT 请求发送的表单对象的 MultiDict 。请注意上传的文件不会在这里,而是在 files 属性中。

  • args
    一个包含解析过的查询字符串( URL 中问号后的部分)内容的 MultiDict 。

  • values
    一个包含 form 和 args 全部内容的 CombinedMultiDict 。

  • headers
    进入请求的标头存为一个类似字典的对象。

  • data
    如果进入的请求数据是 Flask 不能处理的 mimetype ,数据将作为字符串存于此。

  • files
    一个包含 POST 和 PUT 请求中上传的文件的 MultiDict 。每个文件存储为 FileStorage 对象。其基本的行为类似你在 Python 中见到的标准文件对象,差异在于这个对象有一个 save() 方法可以把文件存储到文件系统上。

  • method
    当前请求的 HTTP 方法 (POST , GET 等等)

  • blueprint
    The name of the current blueprint

  • get_json( force=False, silent=False, cache=True )
    Parses the incoming JSON request data and returns it. If parsing fails the on_json_loading_failed() method on the request object will be invoked. By default this function will only load the json data if the mimetype is application/json but this can be overriden by the force parameter.

参数:

- force : if set to True the mimetype is ignored.
- silent : if set to False this method will fail silently and return False.
- cache : if set to True the parsed JSON data is remembered on the request.
  • json
    If the mimetype is application/json this will contain the parsed JSON data. Otherwise this will be None.

    • The get_json() method should be used instead.

从中可以得到一些信息(POST方法),

再次实践

用来测试的 python 代码

  1. import requests
  2. headers = {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
  3. "Accept-Encoding": "gzip,deflate, lzma, sdch",
  4. "Accept-Language": "zh-CN,zh;q=0.8",
  5. "Content-Type": "application/json",
  6. "Connection": "keep-alive",
  7. "Host": "maprun.hustonline.net",
  8. "pgrade-Insecure-Requests": 1,
  9. "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36 OPR/33.0.1990.43"
  10. # data = {'key1': 'value1','key2': 'value2', 'token': 'asdfas'}
  11. data = u'{"token":"adsfa"}'
  12. url = 'http://127.0.0.1:5000/api/photo/praise'
  13. r = requests.post(url, data=data)

从 flask 方面的反馈显示可以使用。

但是

使用 chrome 浏览器中的插件 postman 进行测试时又失败了,截图如下

postman截图

flask 方面的 反馈, 截图如下

flask反馈截图

其中显示 request.data 有数据,而 request.get_json() 没有返回
说明 flask 解析失败

but

stackoverflow 中了解到:

'{"token":"asdfas"}'

 "{\"Hello\":\"Karl\"}"

尝试之后发现成功了。 这样的话应该是 单引号的原因,因为环境是 windows 7 64bit

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注