Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Проблема с chrome.extension.sendMessage (https://javascript.ru/forum/misc/71734-problema-s-chrome-extension-sendmessage.html)

Xopc11 09.12.2017 11:45

Проблема с chrome.extension.sendMessage
 
Доброго времени суток. Помогите пожалуйста с проблемой общения content script'a и background.js. Я пытаюсь сделать расширение для браузера, но столкнулся с такой проблемой: когда загружается страница подключенный к ней content script запрашивает background.js и сообщает id, background же через ajax обращается к БД и отсылает обратно в content script информацию и content script уже работает дальше сам.

Проблема в том, что алгоритм срабатывает правильно только 1 раз. Все последующие запросы равны первому. Т.е. если в первый раз я из background.js получил условные "123" и то и все последующие разы я получаю "123". Но если перезаписать расширение или перезапустить браузер, запустить скрипт с другим id, получить условные "999999" то опять все последующие запросы я буду получать "999999".

Как удалить из память полученные значения, чтобы background не ленился и делал запрос к бд каждый раз, а не только пока не получит первые значения :(

Nexus 09.12.2017 12:03

Скорее всего вы просто криво скрипт написали.

Xopc11 09.12.2017 13:42

Я упростил все что только можно и теперь расширение выглядит примерно так:

ContentScripts.js
chrome.extension.sendMessage('ContentScript', function(backMessage){
	alert('2. Обратно принято из фона: ' + backMessage);
});

background.js
$.ajax({ // Запрос к бд
 url:"http://mysite/background.php", // Запрос к бд
 type:"POST", // Запрос к бд
 data:({url:info.url)}), // Запрос к бд
 dataType:"text", // Запрос к бд
 success: function(data){ // Ответ бд
  if (data.substring(0,4)=="true"){ // Если url есть в бд получает ответ от сервера
   var x = data.substring(data.indexOf("X")+1,); // Достаю из ответа X 
   alert("ПЕРВЫЙ АЛЕРТ   X="+x);									
   chrome.extension.onMessage.addListener(function(request, sender,f_callback){
    if(request=='ContentScript'){ //проверяется, от того ли окна и скрипта отправлено
    alert("ВТОРОЙ АЛЕРТ   X="+x);	
    f_callback("X="+x); //обратное сообщение
   }
   });
 }
}
});

ps в background.js в самом начале стоит chrome.tabs.onUpdated.addListener т.е. ajax срабатывает всегда при обновлении страницы. Так я беру текущий url и отправляю его в bd.


В результате получаю:
Первый прогон:
ПЕРВЫЙ АЛЕРТ X=1
ВТОРОЙ АЛЕРТ X=1
2. Обратно принято из фона: X=1

Второй прогон на другой странице:
ПЕРВЫЙ АЛЕРТ X=2
ВТОРОЙ АЛЕРТ X=1
2. Обратно принято из фона: X=1
ВТОРОЙ АЛЕРТ X=2

Т.е. получается что первый раз скрипт сработал с начала и ajax прошел до конца и chrome.extension.onMessage взял X правильно. Но во второй раз скрипт начинает работать сразу с 2х мест (с начала и с 10й строки) я уже вообще не понимаю ничего... :blink:

Aetae 09.12.2017 22:18

У тебя на каждый onUpdated происходит ajax зпрос и как только он закончен, назначается ещё один обработчик onMessage, старый при этом никуда не девается. При этом возврат результата в хроме работает только для первого назначенного обработчика, остальные отрабатывают только внутри background ничего назад не передавая.
Т.е. через десять апдейтов у тебя висит десять одинаковых
chrome.extension.onMessage.addListener(function(request, sender,f_callback){
    if(request=='ContentScript'){ //проверяется, от того ли окна и скрипта отправлено
    alert("ВТОРОЙ АЛЕРТ   X="+x);  
    f_callback("X="+x); //обратное сообщение
   })

При этом каждый их них хранит в замыкании результат своего ajax вызова.
Не нужно так делать.)

Что тебе нужно, это:
chrome.extension.onMessage.addListener(function(request, sender,f_callback){
  if(request=='ContentScript'){ //проверяется, от того ли окна и скрипта отправлено
    $.ajax({ // Запрос к бд
      url:"http://mysite/background.php", // Запрос к бд
      type:"POST", // Запрос к бд
      data:{url:info.url}, // Запрос к бд
      dataType:"text", // Запрос к бд
      success: function(data){ // Ответ бд
        if (data.substring(0,4)=="true"){ // Если url есть в бд получает ответ от сервера
          var x = data.substring(data.indexOf("X")+1); // Достаю из ответа X
          f_callback("X="+x); //обратное сообщение
        }else{
          f_callback(false); //обратное сообщение      
        }
      }
    })
    return true
  }
})
без всяких onUpdate

Xopc11 11.12.2017 10:45

Цитата:

Сообщение от Aetae (Сообщение 472470)
У тебя на каждый onUpdated происходит ajax зпрос и как только он закончен, назначается ещё один обработчик onMessage, старый при этом никуда не девается. При этом возврат результата в хроме работает только для первого назначенного обработчика, остальные отрабатывают только внутри background ничего назад не передавая.
Т.е. через десять апдейтов у тебя висит десять одинаковых
chrome.extension.onMessage.addListener(function(request, sender,f_callback){
    if(request=='ContentScript'){ //проверяется, от того ли окна и скрипта отправлено
    alert("ВТОРОЙ АЛЕРТ   X="+x);  
    f_callback("X="+x); //обратное сообщение
   })

При этом каждый их них хранит в замыкании результат своего ajax вызова.
Не нужно так делать.)

Что тебе нужно, это:
chrome.extension.onMessage.addListener(function(request, sender,f_callback){
  if(request=='ContentScript'){ //проверяется, от того ли окна и скрипта отправлено
    $.ajax({ // Запрос к бд
      url:"http://mysite/background.php", // Запрос к бд
      type:"POST", // Запрос к бд
      data:{url:info.url}, // Запрос к бд
      dataType:"text", // Запрос к бд
      success: function(data){ // Ответ бд
        if (data.substring(0,4)=="true"){ // Если url есть в бд получает ответ от сервера
          var x = data.substring(data.indexOf("X")+1); // Достаю из ответа X
          f_callback("X="+x); //обратное сообщение
        }else{
          f_callback(false); //обратное сообщение      
        }
      }
    })
    return true
  }
})
без всяких onUpdate

Я так тоже делал. Результат одинаковый. Всегда отправляется только первое сообщение.

Aetae 11.12.2017 11:55

Xopc11,
Ну не знаю что ты там делал, однако приведённый тобой вариант - однозначно ошибочен.
Попробуй в моём варианте заменить
04 url:"http://mysite/background.php", // Запрос к бд
на
04 url:"http://mysite/background.php?" + Math.random(), // Запрос к бд
Возможно дело в кэше.

Xopc11 12.12.2017 08:18

Так даже x не получается взять
--
2. Обратно принято из фона: undefined
--

:cray:

Xopc11 12.12.2017 08:27

Мб есть другие способы передавать сообщения туда обратно?

Xopc11 12.12.2017 11:52

Нашел другой способ который просто идеально работает в моем случае. Я спокойно делаю запрос через ajax и если ответ меня устраивает, отправляю его в контент скрипт.

background.js
chrome.tabs.getSelected(null, function(tab){ //выбирается ид открытого таба, выполняется коллбек с ним
     chrome.tabs.sendRequest(tab.id,{msg:"X="+x}); //запрос  на сообщение
});

ContentScripts.js
chrome.extension.onRequest.addListener(function(req){ //обработчик запроса из background
	alert('3. Принято из фона: ' + req.msg); //выведется переданное сообщение
});

:dance: :dance: :dance: :dance:


Спасибо, что откликнулись. :victory:


Часовой пояс GMT +3, время: 22:50.