Получите доступ к ответу сервера от той же функции javascript, которая инициировала запрос - PullRequest
0 голосов
/ 18 ноября 2011

Имея полный контроль над клиентским и серверным кодом, я хотел бы выполнить следующее:

  • Инициировать запрос к серверу в функции javascript
  • Уметьотказаться от запроса (с точки зрения взаимодействия с пользователем) через указанное время
  • Доступ к информации об ответе (например, URL-адрес перенаправления или часть тела ответа) до выхода из исходной функции (эта часть не подлежит обсуждению; установка интервала окна, например, не обрежет его)

Для меня это звучит как многопоточность, чего, конечно, в javascript нет.Возможно, нет решения, но я исчерпываю свои возможности, прежде чем допустить это.В нерабочем примере ниже функция foo() устанавливает значение iframe src для URL страницы - здесь redirect.aspx, который после небольшой задержки перенаправляет на другую страницу с некоторым UUID в строке запроса.(Примечание: он также может вернуть UUID в скрытом поле в теле ответа или с помощью другой стратегии; я могу это контролировать).

Независимо как страница серверавозвращает результат, моя цель - получить доступ к UUID с сервера до выхода foo().

Обновление: предложенный модульный тест Хотя этот вопрос представляется относящимся к области действия - и, следовательно, решаемым с помощью замыканий (ожидающих испытания) - на самом деле речь идет о непрерывности выполнения,Успешный тест будет состоять из:

  • Создание функции foo()
  • Назначение something.onClick = foo()
  • foo() каким-то образом инициирует вызов сервера и получает URLиз ответа
  • foo() затем вызывает window.open(url); с использованием этого URL
  • Во всех основных браузерах открывается окно (критический случай: IE 7, 8 и 9)

В настоящее время я не знаю стратегии, способной пройти этот тест.

Неработающий образец:

<iframe id="aFrame" src="" height="0" width="0"></iframe>
<script type="text/javascript" language="javascript">
    function foo() {
        var f = document.getElementById("aFrame");
        var loc = "http://localhost:8080/redirect.aspx?after=1000";
        f.src = loc;
        var start = new Date().getTime();
        while (elapsedSince(start < 5000)) { // allow for server response
            // FAIL: this is never true until after foo() exits:
            if (f.src != loc) {
                alert(encodeURIComponent(f.src));
                return true;
            }
        }
        alert("Timeout");
        return false;
    }
    function elapsedSince(startTime) { // omitted safety checks for brevity:
        return new Date().getTime() - startTime;
    }
</script>

Я не туз вAjax-функции, но, насколько я понимаю, они требуют обратного вызова, что означает, что любая возвращаемая информация поступает за пределы инициирующей функции.Fail.

Вышеуказанная стратегия не работает, согласно комментариям в коде js.

Другие стратегии могут включать в себя что-то вроде использования document.createElement() для создания iframe и .insertBefore() для его добавленияв DOM, но я все еще не уверен, что смогу инициировать, чтобы и обращались к любым деталям ответа из одной и той же итерации foo().

Кто-нибудь знает о какой-либо стратегии, которая соответствует вышеуказанным критериям?

1 Ответ

1 голос
/ 18 ноября 2011

Вот код, который пройдет ваш «тест».Он получает URL-адрес с внешней страницы и открывает новое окно с этим URL.

Он не блокируется, когда вы настраиваете прослушиватель для readystatechange событий (обратный вызов).

function foo() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', '/pathname', true);
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
      window.open(xhr.responseText);
    }
  };
};

button.onclick = foo;
...