400 Bad Request while POSTing json to Flask on openshift

400 Bad Request while POSTing json to Flask on openshift

我已经阅读了所有相关的 SO 问题,但在 RedHat 的 openshift 云平台上将 json 发布到我的 Flask 应用程序 运行 时,我仍然遇到此错误(400 - 错误请求)。

这是我的代码:

flaskapp.py

import os
from datetime import datetime
from flask import Flask, request, flash, url_for, redirect, \
     render_template, abort, send_from_directory

app = Flask(__name__)
app.config.from_pyfile('flaskapp.cfg')

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/<path:resource>')
def serveStaticResource(resource):
    return send_from_directory('static/', resource)

@app.route("/test")
def test():
    return "<strong>It's Alive!</strong>"

@app.route('/mine', methods=['POST'])
def mine():
    content = request.get_json(force=True)
    print content

    return "Success!\n"

if __name__ == '__main__':
    app.run(debug=True)

这就是我的 app.py 的样子

#!/usr/bin/env python

# This file may be used instead of Apache mod_wsgi to run your python
# web application in a different framework.  A few examples are
# provided (cherrypi, gevent), but this file may be altered to run
# whatever framework is desired - or a completely customized service.
#
import imp
import os
import sys

try:
  virtenv = os.path.join(os.environ.get('OPENSHIFT_PYTHON_DIR','.'), 'virtenv')
  python_version = "python"+str(sys.version_info[0])+"."+str(sys.version_info[1]) 
  os.environ['PYTHON_EGG_CACHE'] = os.path.join(virtenv, 'lib', python_version, 'site-packages')
  virtualenv = os.path.join(virtenv, 'bin','activate_this.py')
  if(sys.version_info[0] < 3):
    execfile(virtualenv, dict(__file__=virtualenv))
  else:
    exec(open(virtualenv).read(), dict(__file__=virtualenv))

except IOError:
  pass

#
# IMPORTANT: Put any additional includes below this line.  If placed above this
# line, it's possible required libraries won't be in your searchable path
#


#
#  main():
#
if __name__ == '__main__':
  application = imp.load_source('app', 'flaskapp.py')
  port = application.app.config['PORT']
  ip = application.app.config['IP']
  app_name = application.app.config['APP_NAME']
  host_name = application.app.config['HOST_NAME']

  fwtype="wsgiref"
  for fw in ("gevent", "cherrypy", "flask"):
    try:
      imp.find_module(fw)
      fwtype = fw
    except ImportError:
      pass

  print('Starting WSGIServer type %s on %s:%d ... ' % (fwtype, ip, port))
  if fwtype == "gevent":
    from gevent.pywsgi import WSGIServer
    WSGIServer((ip, port), application.app).serve_forever()

  elif fwtype == "cherrypy":
    from cherrypy import wsgiserver
    server = wsgiserver.CherryPyWSGIServer(
      (ip, port), application.app, server_name=host_name)
    server.start()

  elif fwtype == "flask":
    from flask import Flask
    server = Flask(__name__)
    server.wsgi_app = application.app
    server.run(host=ip, port=port)

  else:
    from wsgiref.simple_server import make_server
    make_server(ip, port, application.app).serve_forever()

这是如何发布数据的:

curl -X POST -H "application/json" -d '{"key":"val"}' https://python-bonga.rhcloud.com/mine

N/B: 这在本地主机上工作正常

我发现 POST 在不指定 Content-Type 的情况下使用 curl 默认发送 Content-Type application/x-www-form-urlencoded

http://curl.haxx.se/docs/httpscripting.html#POST

并且如果 Flask 中存在(不同的)mimetype,则 json 数据将不可用;因此 request.get_json(force=True) 失败。

因此,我更改了我的代码,先查找表单数据,然后再查找其他内容

if request.form:
   content = [item for item in request.form]
   print "Content:", ''.join(content)
else:
   content = request.get_json(force=True)
   print "Content:", content