Теги динамического скрипта для запросов JSON ... обнаружение ошибки XXX? - PullRequest
5 голосов
/ 19 сентября 2009

Я делаю кучу json-запросов с динамическими тегами сценария. Можно ли обнаружить, есть ли ошибка в запросе (например, ошибка 503, ошибка 404) и выполнить что-то при обнаружении ошибки?

Ответы [ 7 ]

11 голосов
/ 23 сентября 2009

используйте вместо этого ajax. AFAIK нет способа определить, загружается ли тег сценария или нет, и если нет, то почему он не загружается. Используя ajax, вы можете загрузить json, и он скажет вам, почему он не загрузился.

Используя такую ​​библиотеку, как jQuery, это становится очень просто:

$.ajax({
  type: "GET",
  url: "test.js",
  dataType: "script",
  error: function(xhr, error, exception){
    alert(xhr.status); //Will alert 404 if the script does not exist
  }
});
4 голосов
/ 19 сентября 2009

AFAIK, нет способа получить доступ к коду состояния какого-либо внешнего ресурса, загруженного из документа (например, сценария, стиля или изображения). Даже обнаружение ошибки (скажем, через обработчик событий onerror) не так широко поддерживается в браузерах.

Если все, что вы загружаете, попадает под SOP , используйте XHR , который дает вам доступ к заголовкам ответа. В противном случае вы можете попробовать просмотреть недавно представленный X-домен XHR .

3 голосов
/ 29 сентября 2009

Я предполагаю, что вы хотите, чтобы это работало в междоменных областях, поэтому вы не можете использовать XHR?

Попробуйте создать два тега сценария для каждого запроса: первый выполняет ваш стандартный запрос JSONP, а второй - это обработчик ошибок.

Если первый скрипт-тег выполняется, очистите обработчик ошибок в вашем обратном вызове. Но если первый получит 404, будет запущен обработчик ошибок внутри второго тега скрипта.

Возможно, вы также хотите установить тайм-аут, чтобы справиться с медленным ответом JSONP.

1 голос
/ 30 сентября 2009

Если вы используете jQuery, проверьте jQuery-JSONP , который является плагином jQuery, который выполняет довольно приличную работу по вставке <script> и обнаружению ошибок выборки.

Цитирование со страницы проекта, функции jQuery-JSONP:

  • исправление ошибок в случае сбоя в сети или некорректных ответов JSON,
  • точный контроль именования обратных вызовов и способа их передачи в URL,
  • одновременное выполнение нескольких запросов с одним и тем же именем обратного вызова,
  • два механизма кэширования (на основе браузера и на странице),
  • возможность вручную прервать запрос, как и любой другой запрос AJAX,
  • механизм тайм-аута.
1 голос
/ 26 сентября 2009
0 голосов
/ 29 сентября 2009

Если вам нужно пересечь домены (и страница должна работать переносимо), вы должны использовать динамические теги сценариев.

Если у вас есть доступ к удаленному серверу, вы можете передать код ошибки с сервера, и страница сервера вернет 200.

Независимо от того, имеете ли вы доступ или нет, вы можете использовать setTimeout при создании тега сценария, передавая функцию, которая вызовет ошибку, если она истечет до вызова обработчика jsonp. Убедитесь, что обработчик jsonp прерывается, если обработчик ошибок был вызван.

Вам нужно будет отслеживать каждый запрос через глобальную коллекцию, но вы получите возможность отменять и считать запросы. Это похоже на то, как объекты XHR управляются библиотекой, такой как jQuery.

0 голосов
/ 28 сентября 2009

Если вы хотите обнаружить ошибки, прослушайте событие error и сравните свойство fileName ошибки с именем файла сценария. Если они совпадают, вы обрабатываете ошибку. Дело в том, что я думаю, что свойство fileName доступно только для Firefox и Opera. Большинство браузеров, которые имеют трассировку стека для ошибок, также могут имитировать это поведение.

Вот пример, запрошенный Эриком Брехемье:

var getErrorScriptNode = (function () {
    var getErrorSource = function (error) {
        var loc, replacer = function (stack, matchedLoc) {
            loc = matchedLoc;
        };

        if ("fileName" in error) {
            loc = error.fileName;
        } else if ("stacktrace" in error) { // Opera
            error.stacktrace.replace(/Line \d+ of .+ script (.*)/gm, replacer);
        } else if ("stack" in error) { // WebKit
            error.stack.replace(/at (.*)/gm, replacer);
            loc = loc.replace(/:\d+:\d+$/, "");
        }
        return loc;
    },
    anchor = document.createElement("a");

    return function (error) {
        anchor.href = getErrorSource(error);
        var src = anchor.href,
        scripts = document.getElementsByTagName("script");
        anchor.removeAttribute("href");
        for (var i = 0, l = scripts.length; i < l; i++) {
            anchor.href = scripts.item(i).src;
            if (anchor.href === src) {
                anchor.removeAttribute("href");
                return scripts.item(i);
            }
        }
    };
}());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...