ajax 请求从另一个 ajax 请求调用时给出 500 错误

ajax request gives 500 error when called from another ajax request

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

为了确保 Ajax#2 运行s 在 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

问题的根源在后端。每个请求都使用 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 运行,等待它完成,然后运行第二个命令和 returns 数据。

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