如何在 CherryPy 的 POST 请求中接收 JSON?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3743769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:34:16  来源:igfitidea点击:

How to receive JSON in a POST request in CherryPy?

jsonpostcherrypy

提问by bitcycle

How to receive JSON from POST requests in CherryPy?

如何从 CherryPy 中的 POST 请求接收 JSON?

I've been to this page, and though it does a good job explaining the API, its parameters, and what it does; I can't seem to figure out how to use them to parse the incoming JSON into an object.

我去过这个页面,虽然它很好地解释了 API、它的参数以及它的作用;我似乎无法弄清楚如何使用它们将传入的 JSON 解析为对象。

Here's what I have so far:

这是我到目前为止所拥有的:



import cherrypy
import json

from web.models.card import card
from web.models.session import getSession
from web.controllers.error import formatEx, handle_error

class CardRequestHandler(object):

    @cherrypy.expose
    def update(self, **jsonText):
        db = getSession()
        result = {"operation" : "update", "result" : "success" }
        try:
            u = json.loads(jsonText)
            c = db.query(card).filter(card.id == u.id)
            c.name = u.name
            c.content = u.content
            rzSession.commit()
        except:
            result["result"] = { "exception" : formatEx() }
        return json.dumps(result)

And, here's my jquery call to make the post

而且,这是我发布帖子的 jquery 调用


function Update(el){
    el = jq(el); // makes sure that this is a jquery object

    var pc = el.parent().parent();
    pc = ToJSON(pc);

    //$.ajaxSetup({ scriptCharset : "utf-8" });
    $.post( "http://localhost/wsgi/raspberry/card/update", pc,
            function(data){
                alert("Hello Update Response: " + data);
            }, 
            "json");
}

function ToJSON(h){
    h = jq(h);
    return { 
        "id" : h.attr("id"), 
        "name" : h.get(0).innerText, 
        "content" : h.find(".Content").get(0).innerText
    };
}

回答by btsuhako

Python

Python

import cherrypy

class Root:

    @cherrypy.expose
    @cherrypy.tools.json_out()
    @cherrypy.tools.json_in()
    def my_route(self):

        result = {"operation": "request", "result": "success"}

        input_json = cherrypy.request.json
        value = input_json["my_key"]

        # Responses are serialized to JSON (because of the json_out decorator)
        return result

JavaScript

JavaScript

//assuming that you're using jQuery

var myObject = { "my_key": "my_value" };

$.ajax({
    type: "POST",
    url: "my_route",
    data: JSON.stringify(myObject),
    contentType: 'application/json',
    dataType: 'json',
    error: function() {
        alert("error");
    },
    success: function() {
        alert("success");
    }
});

回答by fumanchu

Working example:

工作示例:

import cherrypy
import simplejson

class Root(object):

    @cherrypy.expose
    def update(self):
        cl = cherrypy.request.headers['Content-Length']
        rawbody = cherrypy.request.body.read(int(cl))
        body = simplejson.loads(rawbody)
        # do_something_with(body)
        return "Updated %r." % (body,)

    @cherrypy.expose
    def index(self):
        return """
<html>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type='text/javascript'>
function Update() {
    $.ajax({
      type: 'POST',
      url: "update",
      contentType: "application/json",
      processData: false,
      data: $('#updatebox').val(),
      success: function(data) {alert(data);},
      dataType: "text"
    });
}
</script>
<body>
<input type='textbox' id='updatebox' value='{}' size='20' />
<input type='submit' value='Update' onClick='Update(); return false' />
</body>
</html>
"""

cherrypy.quickstart(Root())

The doc you linked to describes a couple of CherryPy Tools that are new in version 3.2. The json_intool basically does the above, with some more rigor, and using the new body processing API in 3.2.

您链接到的文档描述了 3.2 版中新增的几个 CherryPy 工具。该json_in工具基本上完成了上述工作,但更加严谨,并使用了 3.2 中新的身体处理 API。

One important thing to note is that jQuery's postfunction doesn't seem to be able to send JSON (only receive it). The dataTypeargument specifies the type of data you expect the XmlHTTPRequest to receive, not the type it will send, and there doesn't seem to be an argument available for you to specify the type you want to send. Using ajax()instead allows you to specify that.

需要注意的一件重要事情是 jQuery 的post函数似乎无法发送 JSON(只能接收它)。该dataType参数指定您希望 XmlHTTPRequest接收的数据类型,而不是它将发送的类型,并且似乎没有一个参数可供您指定要发送的类型。使用ajax()代替允许您指定。

回答by Serguei Fedorov

I found the @cherrypy.tools.json_in()way not very clean since it forces you to use cherrypy.request.json. Instead, the following decorator tries to mimic GETparameters.

我发现这种@cherrypy.tools.json_in()方式不是很干净,因为它迫使您使用cherrypy.request.json. 相反,以下装饰器尝试模仿GET参数。

The following helps this.

以下内容对此有所帮助。

NOTE: This assumes you want to return JSON:

注意:这假设您要返回 JSON:

def uses_json(func):

    @functools.wraps(func)
    @cherrypy.tools.accept(media="application/json")
    def wrapper(*args, **kwargs):

        cherrypy.serving.response.headers['Content-Type'] = "application/json"

        kwargs = dict(kwargs)

        try:
            body = cherrypy.request.body.read()
            kwargs.update(json.loads(body))
        except TypeError:
            pass

        return json.dumps(func(*args, **kwargs)).encode('utf8')

    return wrapper

example:

例子:

 {"foo": "bar"}

get's translated into

get 被翻译成

 @cherypy.expose
 @uses_json
 def endpoint(foo):
      ....