Передача сообщений расширения Chrome при сбое вызова xhr в jQuery - PullRequest
1 голос
/ 15 ноября 2010

Я создаю расширение в Google Chrome, которое выдает запросы к веб-сайтам.

Запросы выдаются «фоновой страницей» по запросу из «скрипта контента»;когда фоновая страница получает запрос на выдачу запроса, она отправляет запрос, анализирует ответ и отправляет ответ обратно в сценарий содержимого, используя sendResponse ().

Все это прекрасно работает при использовании XMLHttpRequest ();но моя проблема заключается в том, что если я хочу выдавать запросы с использованием jQuery .get () или .load (), то при сбое запросов они молча завершаются и ответ никогда не отправляется в сценарий содержимого.

ЕслиЯ регистрирую обработчик событий в .ajaxError (), ошибка отлавливается, но из этого обработчика событий я, очевидно, не могу вызвать sendResponse (), потому что я получаю следующую ошибку Chrome:

«Попытка использовать отключенный объект порта»

При поиске этой ошибки извлекается только исходный код Chrome, где находится этот текст, поэтому он не очень полезен.

Короче говоря, мой вопрос: возможно ли использовать jQuery.get() в фоновом сценарии расширения Chrome, и все еще сможете отправить ответ на сценарий содержимого, если запрос не выполнен?(и если да, то как)

Ответы [ 2 ]

1 голос
/ 17 ноября 2010

С этим трудно справиться напрямую без примера кода (как вы передавали sendResponse обработчику ошибок?), Но я думаю, что есть несколько альтернатив для самостоятельного построения XHR.

  • Отвечать асинхронно : вы можете немедленно отправить пустой запрос в скрипт контента, а затем позднее установить новое соединение со скриптом контента для отправки ответа.Сценарий содержимого должен будет добавить прослушиватель для сообщений.Очевидно, что если вы делаете несколько таких запросов, вам нужно, чтобы некоторые токены передавались взад и вперед, чтобы вы могли сопоставлять ответы на их исходные запросы.
  • Использовать $.ajax(): это позволяет вам указать как успешный, так и обратный вызов ошибки в строке;если вы можете успешно sendResponse из обратного вызова success, вы также можете сделать это из обратного вызова ошибки.
  • Создать долгоживущий порт : долгоживущие соединения позволяет вам публиковать сообщение в скрипте содержимого в любое время.

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

0 голосов
/ 16 ноября 2010

Посмотрев на код, чтобы посмотреть, смогу ли я извлечь его для построения рабочего примера (в ответ на комментарий serg), я не думаю, что то, что я хочу сделать, возможно с jQuery.

В jQuery при сбое вызова ajax вызывается событие ошибки (для того, чтобы оно было перехвачено обработчиком события .ajaxError ()), а затем функция завершается / возвращается.Когда запускается обработчик .ajaxError (), функция не работает.(В этом, я полагаю, и заключается весь смысл асинхронной системы событий в JS).

Теперь я только догадываюсь, но я думаю, что в Chrome канал связи между скриптом контента ифоновый скрипт закрывается при запуске функции слушателя;нельзя отправить ответ из фонового сценария в сценарий содержимого после завершения функции прослушивателя, что я пытался сделать при обработке ошибки ajax в обработчике событий.

Итак, чем я закончилВ результате была реализована функция ajax, которая на самом деле отправляет обратно полный объект: если вызов завершается неудачно, он возвращает тот факт, что произошла ошибка, вместе с кодом ошибки, так что функция вызывающей стороны (фактически, обратный вызов) можетразберитесь с этим и отправьте ответ на скрипт контента.

Это всего несколько строк, и (я думаю) довольно общий, так что вот оно:

function xhr(url, callback) {
    var req = new XMLHttpRequest();
    req.open("GET", url, true);
    req.onreadystatechange = function() {
        if (req.readyState == 4) {
            var resp = {
                "url": url,
                "status": req.status
                };
            if (req.status == 200) {
                resp.html = req.responseText;
                resp.outcome = "ok";
                }
            else {
                resp.outcome = "error";
                }
            callback(resp);
            }
        }
    req.send(null);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...