简体   繁体   English

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

[英]web2py - ajax call returns 404 or fails to process parameters

I have a function defined in my controller: 我在控制器中定义了一个函数:

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

And in my view I use jQuery $.ajax() to call it in the view: 在我看来,我使用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',
   });

And put simply I cannot get this to work. 简而言之,我无法解决这个问题。

  • if I use type: 'POST' then the function is called as expected but the path parameter never makes it through to the controller function (it is just None ) 如果我使用type: 'POST'则会按预期方式调用该函数,但path参数永远不会将其传递到控制器函数(它只是None
  • if I change it to type: 'GET' web2py decides the function does not exist at all and returns a HTTP 404 (and this remains even if I remove .json from the URL). 如果我将其更改为type: 'GET' GET'web2py决定该功能根本不存在,并返回HTTP 404(即使我从URL中删除了.json ,该功能仍然存在)。 No errors in the web2py error log. web2py错误日志中没有错误。

Web2py seems to behave quite strangely here - to get the POST working in the first place I had to explictly set contentType: "application/json" otherwise I'd see a 404 there as well, despite the data:'json' already there. Web2py似乎在这里表现得很奇怪-首先要使POST工作,我必须明确设置contentType: "application/json"否则尽管有data:'json' ,我也在那里看到了404。

Has anyone else seen and worked around this behaviour? 是否有其他人看到过该行为并已在其中工作? I don't care if the call is GET or POST, I just want it to work! 我不在乎呼叫是GET还是POST,我只是希望它能正常工作!

There are a few problems. 有一些问题。 First, when a web2py action returns a dictionary, web2py looks for an associated view to execute (based on the path of the action as well as the extension). 首先,当web2py操作返回字典时,web2py将根据操作的路径以及扩展名查找要执行的关联视图。 In this case, it will look for a view with the path /views/controller_name/get_config_values.json . 在这种情况下,它将查找路径为/views/controller_name/get_config_values.json的视图。 If it doesn't find that view, it may attempt to use the generic.json view, but only if you have explicitly enabled the generic view via response.generic_patterns (in the scaffolding app, all generic views are enabled by default, but only for local requests). 如果找不到该视图,则可能会尝试使用generic.json视图,但generic.json是您已通过response.generic_patterns显式启用了通用视图(在脚手架应用中,所有通用视图均默认启用,但仅用于本地请求)。 Otherwise, you will get a 404 error (if you inspect the body of the error message in the browser developer tools, you should see a message about an invalid view). 否则,您将收到404错误(如果您在浏览器开发人员工具中检查错误消息的正文,则应该看到有关无效视图的消息)。

Second, to post JSON via jQuery, you have to convert your Javascript object to a JSON string: 其次,要通过jQuery发布JSON,您必须将Javascript对象转换为JSON字符串:

data: JSON.stringify(
    {
        path: page_path
    }
),

With the above, you should now have the value of page_path in request.vars.path on the server. 通过以上操作,您现在应该在服务器上的request.vars.path具有page_path的值。

Finally, if you request a .json URL from web2py, it will set the Content-Type response header to "application/json". 最后,如果您从web2py请求一个.json URL,它将Content-Type响应头设置为“ application / json”。 However, based on your Javascript code, it appears you want to return HTML (given that you are placing the results into a div on the page). 但是,根据您的Javascript代码,您似乎想要返回HTML(假设您将结果放入页面上的div中)。 So, you should probably not use the .json extension in the request (you can also explicitly tell jQuery that the response is HTML by setting dataType: 'html' ). 因此,您可能不应在请求中使用.json扩展名(也可以通过将dataType: 'html'设置为jQuery明确告诉jQuery响应是HTML)。

So, try the following: 因此,请尝试以下操作:

$.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',
});

Then either create a get_config_values.html view that generates the desired HTML from the returned dictionary, or otherwise have the get_config_values function directly return an HTML string. 然后创建一个get_config_values.html视图,该视图从返回的字典中生成所需的HTML,或者让get_config_values函数直接返回HTML字符串。

If you instead do want to return JSON to the browser, then you will need to change your success callback to process the JSON before attempting to place it in a div. 如果您确实希望将JSON返回到浏览器,那么您将需要更改success回调以处理JSON,然后再尝试将其放入div中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM