【问题标题】:Not able to call the API and redirect at the same time无法同时调用 API 和重定向
【发布时间】:2017-04-24 09:02:22
【问题描述】:

我正在尝试使用 XMLHttpRequest 调用 API,然后在成功状态下,我尝试将其重定向到下一页,但重定向正在运行,并且调用不起作用,如果我删除重定向,调用将起作用..

我不确定在调用 API 时是否无法重定向,或者我做错了什么,所以请检查并建议

这是我写的AJAX调用成功的代码。

if (response.status === true) {
  var api = "https://api-voice.solutionsinfini.com/v1/?api_key=****&method=dial.click2call&output=xml&caller=****&receiver=" + sessionStorage.fullNumber;

  // Calling the API
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET", api);
  xhttp.onreadystatechange = function() {
    if (xhttp.readyState == 4 && xhttp.status == 200) {
      document.getElementById('myModalCallback').style.display = 'none';
      window.location.href = "/anotherpage";
    }
  };
  xhttp.send();
  document.getElementById('myModalCallback').style.display = 'none';
}

【问题讨论】:

  • 你的重定向在你得到状态200时有效,所以你的api也有效,那么问题出在哪里?
  • 问题是,通过将重定向放在 onreadystatechange 函数中,api 不起作用,如果我放在外面,则重定向不起作用.. api 应该生成一个电话,但那是不使用重定向
  • 你读过这个问题吗? stackoverflow.com/questions/5183178/…
  • 你能用jQuery代替吗?

标签: javascript ajax redirect xmlhttprequest


【解决方案1】:

我怀疑代码还可以,但是您没有收到 200 响应。您可以通过两种方式进行调试:

  1. 使用以下代码检查来自您的 api 服务器的响应代码(请注意我更改了 API 端点,此代码运行良好)

 

var api = "//freegeoip.net/json/?callback=?";

// Calling the API
var xhttp = new XMLHttpRequest();
xhttp.open("GET", api);
xhttp.onreadystatechange = function() {
    if (xhttp.readyState == 4 && xhttp.status == 200)
    {
      console.log('yass, 200 response');
      document.getElementById('myModalCallback').style.display = 'none';
      window.location.href = "/otherpage";
    } else if (xhttp.readyState == 4)
    {
      // got a bad response
      console.log('ouch, '+xhttp.status+' response');
    } else {
      console.log('ready state change',xhttp.readyState);
    }
};
xhttp.send();
document.getElementById('myModalCallback').style.display = 'none';
  1. 在浏览器的网络选项卡中检查您从 API 获得的响应

我真的建议使用类似 jQuery 的 ajax 调用(跨浏览器效果很好),而不是直接使用 XMLHttpRequest 对象:http://api.jquery.com/jquery.ajax/

【讨论】:

    【解决方案2】:

    这一行是异步的,因为 DOM 更改是排队的,因此浏览器可以一起更新它们:

    document.getElementById('myModalCallback').style.display = 'none';
    

    重定向发生在浏览器更新 DOM 之前。为了解决这个问题,您需要将重定向放在事件循环的末尾。一种方法是使用 setTimeout。

    查看此答案以获取有关 DOM 更新队列的更多说明:Update the DOM vs Rerender the View In Angular

    事件循环:https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

    【讨论】:

      【解决方案3】:

      您是否可以从代码中等待 getElementById('myModalCallback') 在重定向之前消失?这可能就像它在重定向之前没有消失一样。如果您需要在重定向之前查看“display:none”效果,您必须在某些超时后进行重定向。

      类似这样的:

      if (xhttp.readyState == 4 && xhttp.status == 200) {
        document.getElementById('myModalCallback').style.display = 'none';
        window.setTimeout(function(){
         window.location.href = "/anotherpage";
        }, 1000);
      }
      

      【讨论】:

      • 如何确定 api 任务会在 1 秒内完成?
      • 1 秒 - 如果需要,仅用于接口反应的超时。当 (xhttp.readyState == 4 && xhttp.status == 200) 为真时 - 您的调用已经完成并返回 HTTP 状态 200。JavaScript 可以在执行时阻止用户界面。超时仅用于给浏览器执行命令 display:none 的时间,如果你需要的话。
      【解决方案4】:

      您是否尝试在您的 onreadystatechange 函数的第一行添加一个 console.log('xhttp', xhttp) 来检查您的预期结果?

      【讨论】:

        【解决方案5】:

        您是否尝试过使用 XMLHttpRequest 的新语法?

        function onResponse () {
          console.log(this.responseText);
          window.location.href = 'http://www.google.com';
        }
        
        var oReq = new XMLHttpRequest();
        oReq.addEventListener("load", onResponse);
        oReq.open("GET", "https://httpbin.org/get");
        oReq.send();
        

        【讨论】:

          猜你喜欢
          • 2020-08-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多