【问题标题】:Why can't I browse to other pages after making an ajax call?ajax调用后为什么不能浏览其他页面?
【发布时间】:2017-02-03 16:25:15
【问题描述】:

在旧版 MVC 5 Web 应用程序中,我希望用户能够在单击一个按钮后继续浏览,该按钮对长时间运行的操作进行 ajax 调用。

注意:操作返回void - 我对响应不感兴趣)

当我点击按钮时,在操作完成之前我无法发出任何其他请求。

编辑:这里是ajax代码:

$('#EmailReport') //
    .click(function() {
        $.ajax({
            type: "POST",
            url: '/Home/EmailReport',
            complete: function() {console.log("done")},
            async: true
        });
    });

控制器

[HttpPost]
public async Task EmailReport()
{
   // for testing - sleep for 10 seconds
   await Task.Delay(TimeSpan.FromSeconds(10));
}

这是 Chrome 开发工具中的截图:

EmailReport 是 ajax 调用,底部的两个请求是我试图浏览到另一个页面 - 如您所见,第一个请求是 pending,任何后续请求都是 cancelled

有没有人知道如何解决或解决此问题?

【问题讨论】:

  • 与其关注客户端,不如看看服务器 - 长时间运行的操作在处理它时是否完全占用了服务器?
  • 在“EmailReport”操作中创建一个线程,该线程可以在后台运行并返回 HTTP 200 响应。不要等待通过回复。 AJAX。
  • 您是否在该操作中使用会话?
  • 正是你的问题

标签: javascript jquery ajax asp.net-mvc


【解决方案1】:

最简单的方法如下:

Task t = new Task(() => TimeSpan.FromSeconds(10));
t.Start();

与线程相比,对于长时间运行的作业,最好使用任务,以避免核心关联和更好的 CPU 利用率。

【讨论】:

    【解决方案2】:

    看来Navigator.sendBeacon() api 将服务于您的目的。它用于通过 HTTP 将少量数据异步传输到 Web 服务器。虽然这是一项实验性技术,Chrome 39+、Firefox 31+、opera 26+ 都支持,但其他浏览器有一个polyfill

    【讨论】:

      【解决方案3】:

      问题在于,您的操作等待任务完成。不要让它等待,一开始任务就返回。

      [HttpPost]
      public void EmailReport()
      {
         // for testing - sleep for 10 seconds
         var myTask = Task.Delay(TimeSpan.FromSeconds(10));
         myTask.Start();
      }
      

      您的请求被取消,因为它是一个页面重定向请求,并且在发出新的页面重定向请求时会取消旧的页面重定向请求(例如,当您点击链接 2 次时,第一次点击被忽略)。这是浏览器实现它的方式。它与您的问题的根源无关。

      【讨论】:

      • 感谢您的回答 - 我进行了此更改,但现在当我查看开发工具网络选项卡中的 ajax 调用时,我收到 500 错误?
      • 你能发布异常吗?您可以在Global.asaxApplication_Error 方法和Server.GetLastError() 中找到异常。见forums.asp.net/t/1926670.aspx?How+to+get+last+exception
      【解决方案4】:

      使用后台进程

      [HttpPost]
      public JsonResult EmailReport()
      {
          Thread email= new Thread(delegate ()
         {
                generatereports();
         });
         email.IsBackground = true;
         email.Start();
         return null; 
      }
      

      【讨论】:

      • 您好,感谢您的回复。不幸的是,我使用此代码遇到了同样的问题
      猜你喜欢
      • 1970-01-01
      • 2020-12-12
      • 2014-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多