【问题标题】:Decoding JSON with python using Appengine使用 Appengine 使用 python 解码 JSON
【发布时间】:2013-01-09 08:33:16
【问题描述】:

我有以下代码从一个简单的 3 输入表单中检索值:

//retrieves data from a form
var $form = $( this ),
    prgname= $form.find('input[name="prg"]').val(),
    startDate = $("#startdate").datepicker({ dateFormat: 'yy-mm-dd' }).val(),
    endDate = $("#enddate").datepicker({ dateFormat: 'yy-mm-dd' }).val();

以下代码将请求发送到服务器:

var request = $.ajax({
      url: "/prg/",
      type: "post",
  data: JSON.stringify({prg:  prgname, start:startDate, end:endDate}),
  contentType: 'application/json',
  dataType: 'json',
      success: function() {},
      error: function (jqXHR, textStatus, errorThrown){};

在服务器端使用 python 和 webapp2 我正在执行以下操作,(这里是我不确定的地方)

import json

class PrgHandler(webapp2.RequestHandler):
    def post(self):
        prg= cgi.escape(self.request.POST['prg'])
        start_date = cgi.escape(self.request.POST['start'])
        end_date = cgi.escape(self.request.POST['end'])

        #some code to write to db here
        ....
        #if successful return a success message
        if success:
            success_msg = [{'class': 'success', 'msg': 'Successfully saved to the database'}]
        else:
            success_msg = [{'class': 'error', 'msg': 'Could not saved to the database'}]

        data_string = json.dumps(success_msg)
        self.response.headers.add_header('content-type', 'application/json', charset='utf-8')   
        self.response.write(data_string)

当我得到响应时,它会跳过成功函数并直接进入错误。

记录错误值我没有得到任何有意义的东西:

the error is:
The text status is:error
The jqXHR is:[object Object] 

Chrome 的控制台给了我错误:

Resource interpreted as Document but transferred with MIME type application/json:

我查了一下,SO上的解决方案不起作用,我认为这是服务器端代码的错误:

self.response.headers.add_header('content-type', 'application/json', charset='utf-8')

如果我注释掉上面的行,我在 chrome 中没有错误,我只是在空白页面上返回响应,其中包含以下格式的正确值:

[{"msg": "Successfully saved to the database", "class": "success"}]

在上述情况下,它确实保存到数据库中,所以我似乎找不到任何错误,除了标题之外,根本不知道如何继续!

编辑 似乎来自服务器端的错误我删除了以下行: event.preventDefault();

从我的脚本中,它现在引起了所有问题,至少我清楚地知道问题出在哪里。这是由于错误地获取发布的数据,我将如何以正确的方式做到这一点?我尝试了以下方法:

json_data = self.request.GET.items()
decoded = json.loads(json_data)

但我得到一个 TypeError: expected string or buffer 在以下行: json_data = self.request.GET.items()

【问题讨论】:

    标签: python json google-app-engine webapp2


    【解决方案1】:

    好的,所以我设法弄清楚了这一点,并认为我会发布对我有用的答案,以帮助任何寻找此信息的人,因为 webapp2 文档在“获取”已发布的 json 数据时没有那么有用。

    在客户端我做了以下操作:

    var request = $.ajax({
        url: "/some/url/",
        type: "POST",
        data: JSON.stringify([{someval: val1, someval2:val2, someval3:val3}]),
        contentType: "application/json",
        dataType: 'json',
        beforeSend: function() {
            $('#loading-div').show();
        },
        complete: function(){
            $('#loading-div').hide();
        },
        success: function(response, textStatus, jqXHR){}
    });
    

    我无法立即找出问题的原因是因为我删除了以下行以及一些注释掉的行,这阻止了页面在发布后重定向。这是所有奇怪、不相关和无用的错误消息的来源:

    event.preventDefault();
    

    在服务器端获取要发布到 appengine 的 json 数据,请执行以下操作:

    jdata = json.loads(cgi.escape(self.request.body))
        for vals in jdata:
            val1 = vals['someval']
            val2 = vals['someval2']
            val3 = vals['someval3']
    

    以上是问题的根源,我做得不对,如果没有客户端的上一行,就无法解决。

    无论如何,一旦你有了数据,你就可以做任何你需要做的处理,一旦你完成并需要发回一个 json 响应,添加以下行:

    //the data would look something like this 
    data = {'return_value': val1, 'return_value2': val2,
            'return_value3': val3, 'return_value4': val4}
    
            return_data = json.dumps(data)
            self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
            self.response.write(return_data)
    

    几乎再次忘记在客户端使用 jquery 访问从服务器发回的变量,这非常直接......执行以下操作:

     success: function(response, textStatus, jqXHR){
            console.log(response.return_value);
            console.log(response.return_value2);
            console.log(response.return_value3);
     }
    

    希望这对寻求此信息的人有所帮助。

    【讨论】:

    • 是的,这在 webapp2 文档中根本没有很好地记录。您可能希望 json 内容位于 request.POST 变量中。
    【解决方案2】:

    看看你的调试器。您在帖子中收到一个 JSON 字符串(webapp2 multidict)。您必须使用 json.loads 解码此字符串,从而生成一个 python 对象。

    这是我发送和接收 json 的 jquery 代码:

    function gaeQuery(request) {
        var url = "/query";
        var payload = {'jsondata' : JSON.stringify(request)};
        $.post(
        url, 
        payload, 
        function(response) {
            procesResponse(response);
        },  // succes response callback 
        'json',  // response contains JSON content, and will be decoded in a js object
        {
            contentType: "application/json;charset=utf-8", // send JSON content
            timeout: 20000,
            tryCount: 0,
            retryLimit: 3, // max 3 retries             
            error: function(xhr, textStatus, errorThrown) { // error handling callback
                if (textStatus === 'timeout') {
                    this.tryCount++;
                    if (this.tryCount <= this.retryLimit) { //try again until retryLimit
                        $.ajax(this);
                        return;
                    }
                    alert('We have tried ' + this.retryLimit + ' times and it is still not working. We give in. Sorry.');
                    return;
                }
                if (xhr.status === 500) { // internal server error
                    alert('Oops! There seems to be a server problem, please try again later.');
                } 
                else {
                    alert('Oops! There was a problem, sorry.'); // something went wrong
                }
            }
        }
        );
    }
    

    【讨论】:

    猜你喜欢
    • 2013-04-07
    • 2011-01-20
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多