【问题标题】:ajax request gives 500 error when called from another ajax request从另一个 ajax 请求调用时,ajax 请求给出 500 错误
【发布时间】:2016-12-01 01:38:41
【问题描述】:

我有两个 ajax 请求,一个将数据发送到后端(我们称之为 Ajax#1),然后一个使用发送的数据将内容加载到前端(Ajax#2)。

为了确保 Ajax#2 在 Ajax#1 之后运行,我尝试将包含 #2 的函数作为回调传递给包含 #1 的函数,在 #1 完成后调用它。

但是,这似乎总是会产生 500 错误。

Ajax #2 自己运行良好(当按下按钮触发时),但是当从 Ajax #1 调用时,它总是给出 500 错误。

知道我在这里做错了什么吗?

var initialize = function(){

  //Load settings config on page load (this works fine)
  load_settings_config();

  //Should apply settings on button press, and load those new settings to front end
  $("#apply-sysconfig-button").click(function(){
    apply_settings_config(load_settings_config);
  });

  //manual load settings button (This works fine)
  $("#load-settings-button").click(function(){
    load_settings_config();
  });

};

apply_settings_config = function(callback){

  //Not shown - Grabs user input from html input and select elements and loads into the variable 'settings' to be sent to back end
  //Ajax#1
  $.ajax({
      method: "POST",
      contentType: 'application/json',
      url: "/applynewsettings",
      data: JSON.stringify(settings)
  })
  .done(function(sysconfig_err_msg){
    //prompt user with error message if user input is invalid
    $("#static-ip-input-err").html(sysconfig_err_msg);

    //This does not work - gives 500 error
    callback()
  });
};

load_settings_config = function(){
  //loads the new/updated settings back to front end
  //Ajax#2
  $.ajax({
    method: "GET",
    contentType: 'application/json',
    url: "/loadinterfaceinfo"
  })
    .done(function(interface_info_new){
        interface_info = JSON.parse(interface_info_new);
        interface_selected = $("#interface-dropdown option:selected").text()
        populate_interface_info(interface_selected);

  });
};

注意我也试过了

 $("#apply-sysconfig-button").click(function(){
    apply_settings_config();
    load_settings_config();
  });

不出所料,这会导致加载经常在应用完成之前运行。

我尝试像这样在 ajax 中直接调用该函数:

apply_settings_config = function(){

  //Not shown - Grabs user input from html input and select elements and loads into the variable 'settings' to be sent to back end
   //Ajax#1
  $.ajax({
      method: "POST",
      contentType: 'application/json',
      url: "/applynewsettings",
      data: JSON.stringify(settings)
  })
  .done(function(sysconfig_err_msg){
    //prompt user with error message if user input is invalid
    $("#static-ip-input-err").html(sysconfig_err_msg);

    //This does not work - gives 500 error
    load_settings_config()
  });
};

这给出了相同的 500 错误。

我似乎遗漏了如何使用异步 get/post 请求进行回调的部分内容。任何帮助将不胜感激


编辑 要求查看后端。我不确定这将如何帮助考虑到这两个请求在大多数情况下都可以正常工作。只有当 ajax 请求嵌套时,外部才不起作用,但无论如何它们都在这里:

@app.route("/applynewsettings", methods=['POST'])
def apply_new_settings():
    global sys_settings
    sia_err_msg = ""

    if request.method == 'POST':
        sys_settings = request.json

    sys_settings = convertToASCII(sys_settings)

    mtu = sys_settings["mtu"]
    ip_address = sys_settings["ip_address"]
    subnet_mask = sys_settings["subnet_mask"]
    gateway = sys_settings["gateway"]
    interface = sys_settings["interface"]

    #Not shown - validation and build string to send command

    if "sia" in sia_cmd:
        cli.sendCmd(sia_cmd)
        sia_err_msg = "Sucess!"
        print "SEND CMD: "+sia_cmd
    else:
        print "sia cmd was invalid: "+"'"+sia_cmd+"'"
        sia_err_msg = sia_err_msg + "Apply Settings Failed!"

    return sia_err_msg

#Sends cmd through telnet cli, parses response, returns to front end
@app.route("/loadinterfaceinfo")
def load_interface_info():
    #Sends cmd through telnet cli & parses response
    interface_dict = run_cmd(cli,"get_interface_info")
    #must encode as json to send to front end
    interface_dict = json.JSONEncoder().encode(interface_dict)
    #send to front end
    return interface_dict

【问题讨论】:

  • 你能找出 500 错误是什么吗?另外,不确定是否重要,但您的 URL /applynewsetttings 似乎包含一个额外的 't'
  • 没有关于服务器端的任何信息,这是错误的根源,无济于事
  • 代替data: JSON.stringify(settings)试试data: settings
  • @Beno 500 错误是 GET 127.0.0.1/loadinterfaceinfo500(内部服务器错误)。 “设置”很好,但我在我调用/定义它的所有地方都做了错字(复制粘贴它以确保我没有打错字 - 具有讽刺意味的是),所以这与我的问题无关
  • 好的,我想通了。两个 Ajax 请求都涉及从 telnet cmd 发送或接收数据。问题是,当一个从另一个内部运行时,它会创建一个竞争条件,其中第二个 cmd 失败,因为第一个 cmd 仍在运行过程中。

标签: javascript jquery ajax jquery-callback


【解决方案1】:

问题的根源在于后端。每个请求都使用 telnet 发送命令。当两个命令以快速顺序运行时(一个 ajax 请求在另一个内部),第二个 telnet 命令将挂起,因为第一个命令尚未完成。为什么这会导致 500 错误(这让我相信第二个 ajax 请求根本没有与后端通信)我不太确定。

一个快速(且草率)的解决方法是添加超时以使第二个 ajax 在运行前等待一秒钟。

像这样:

  $.ajax({
      method: "POST",
      contentType: 'application/json',
      url: "/applynewsettings",
      data: JSON.stringify(settings)
  })
  .done(function(sysconfig_err_msg){
    $("#static-ip-input-err").html(sysconfig_err_msg);

    setTimeout(function(){ load_settings_config(); }, 1000);

  });

更好(也更困难)的解决方案是确保在后端识别 telnet 正在被另一个正在运行的命令使用,等待它完成,然后运行第二个命令并返回数据。

虽然不知道该怎么做。欢迎提出想法。

【讨论】:

  • 我缺乏理解可能是因为我从未使用过 telnet,但是您的 ajax 如何/为什么在请求完成之前完成回调触发?
  • @Jecoms 第一个ajax请求通过python(使用flask)通过telnet发送数据并且不依赖telnet返回任何东西(如果有一个错误消息,python会返回一个带有错误消息的字符串,但那是完全由python后端处理)。因此,如果通过 ajax 发送的命令需要 0.5 秒才能处理和完成,那么在此期间发送的任何其他命令都将不起作用,因为 telnet 连接很忙。第二个 ajax 请求实际上依赖于 telnet 的响应,而不仅仅是向其发送数据,因此它在无法发送或接收任何内容时中断。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 2017-04-15
  • 2015-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多