web2py - ajax调用返回404或无法处理参数

时间:2015-07-12 10:19:09

标签: javascript jquery ajax web2py

我的控制器中定义了一个函数:

def get_config_values():
    path = unescape(request.vars['path'])
    config = get_config_as_dict(path)
    return dict(config)

在我看来,我使用jQuery $.ajax()在视图中调用它:

$.ajax({
      url: "{{=URL('get_config_values.json')}}", 
      contentType: "application/json; charset=utf-8", 
      data: {
         path: page_path,
      },
      error: function(x, y, z) {
         show_error(x.responseText, y, z);
         hide_drawer();
      },
      success: function(data) {
         $('#drawer_content').html(data);
      },
      type: 'POST',
   });

简单地说,我无法让它发挥作用。

  • 如果我使用type: 'POST',则按预期调用该函数,但path参数永远不会通过控制器函数(它只是None
  • 如果我将其更改为type: 'GET' web2py决定根本不存在并返回HTTP 404(即使我从网址中删除了.json,这仍然存在)。 web2py错误日志中没有错误。

Web2py似乎在这里表现得非常奇怪 - 为了让POST工作在第一位我必须明确地设置contentType: "application/json"否则我会在那里看到404,尽管data:'json'已经存在

有没有其他人看到并解决过这种行为?我不在乎呼叫是GET还是POST,我只是想让它起作用!

1 个答案:

答案 0 :(得分:1)

有一些问题。首先,当web2py操作返回字典时,web2py会查找要执行的关联视图(基于操作路径和扩展名)。在这种情况下,它将查找路径为generic.json的视图。如果它找不到该视图,它可能会尝试使用response.generic_patterns视图,但前提是您已通过data: JSON.stringify( { path: page_path } ), 明确启用了通用视图(在脚手架应用中,所有通用视图均为默认情况下启用,但仅适用于本地请求)。否则,您将收到404错误(如果您在浏览器开发人员工具中检查错误消息的正文,则应该看到有关无效视图的消息)。

其次,要通过jQuery发布JSON,您必须将Javascript对象转换为JSON字符串:

page_path

通过上述内容,您现在应该在服务器上的request.vars.path中拥有.json的值。

最后,如果您从web2py请求.json网址,则会将Content-Type响应标头设置为" application / json"。但是,根据您的Javascript代码,您似乎想要返回HTML(假设您将结果放在页面上的div中)。因此,您可能不应在请求中使用dataType: 'html'扩展名(您也可以通过设置$.ajax({ url: "{{=URL('get_config_values')}}", contentType: "application/json; charset=utf-8", data: JSON.stringify({ path: page_path, }), error: function(x, y, z) { show_error(x.responseText, y, z); hide_drawer(); }, success: function(data) { $('#drawer_content').html(data); }, type: 'POST', }); 明确告诉jQuery响应是HTML。)

所以,请尝试以下方法:

get_config_values

然后创建一个get_config_values.html视图,从返回的字典中生成所需的HTML,或者让success函数直接返回HTML字符串。

如果您确实想要将JSON返回给浏览器,那么在尝试将JSON放入div之前,您需要更改local proto1 = Proto("proto1","First Layer") local page = ProtoField.uint16("proto1.page", "Page", base.HEX) local proto2 = ProtoField.bytes("proto2","Second Layer") local len = ProtoField.uint8("proto2.len", "Payload Length") proto1.fields = {page, proto2, len} local function proto2_dissect(buffer, pinfo, tree) pinfo.cols.protocol = "proto2" local ptree = tree:add(proto2, buffer()):set_text("Second Layer") ptree:add(len, buffer(1,2)) end function proto1.dissector(buffer, pinfo, tree) pinfo.cols.protocol = proto1.name; local ptree = tree:add(proto1,buffer(1,5)) ptree:add(page, buffer(1,2)) proto2_dissect(buffer(6,4):tvb(), pinfo, tree) end DissectorTable.get("tcp.port"):add(3456, proto1) 回调以处理JSON。