Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   chrome.tabs.sendMessage (https://javascript.ru/forum/misc/65784-chrome-tabs-sendmessage.html)

Артист 07.11.2016 20:34

chrome.tabs.sendMessage
 
Подскажите пожалуйста, как мне отправить сообщение из 2го в 1й скрипт?

Смотрел вот тут описание, но без примера я ничего не понимаю...

Есть 2 скрипта, 1й(background.js) висит в приложении постоянно, 2й(maps.js) подключается только к определённым страницам.

В background.js
chrome.runtime.onMessage.addListener // Отлов сообщений
(
	function(request, sender, sendResponse)
	{
		switch(request.id) // Это типа идентификатор сообщений
		{
			case 2: // GET запрос
			{
				GetHttpRequest(request.href, {rid: request.rid})
				break
			}
		}
	}
)

Это дополнительная информация из background.js
function GetHttpRequest(href, arg) // Запрос
{
	var xhr = new XMLHttpRequest()
	xhr.withCredentials = true
	xhr.onreadystatechange = function(e)
	{
		e.data = arg
		ProcessRequestChange.apply(this, arguments)
	}
	xhr.open('GET', href, true)
	xhr.send(null)
}
function ProcessRequestChange(e) // Обработчик запроса
{
	var xhr = this

	if(xhr.readyState != 4) return
	if(xhr.status == 200)
	{
		var html = xhr.responseText
		
		switch(e.data.rid) // Это типа идентификатор запроса
		{
			case 3: // Покопаться в ответе на 'http://www.site.ru/bla-bla.php'
			{
				// Некий код который записывает необходимую информацию в str убрал для экономии
				var str = 'ответ' // Пусть будет это ответом
				
				chrome.tabs.query // Вроде это какое - то событие открытия(или получения) вкладок?
				(
					{active: true, currentWindow: true}, // Х.з
					function(tabs)
					{
						chrome.tabs.sendMessage // Это то, что отправляет ответное сообщение
						(
							tabs[0].id, // Х.з, наверное идентификатор вкладки, куда отправить?
							{greeting: "hello"}, // Это я так понял и есть ответ?
							function(response) // А это вообще не нужно вроде...
							{
								console.log(response.farewell);
							}
						)
					}
				)
				break
			}
		}
	}
}

В maps.js:
chrome.runtime.sendMessage // Отправить сообщение в background.js
(
	{id: 2, href: 'http://www.site.ru/bla-bla.php', rid: 3}, // Сделать запрос на адрес
	function(response) // Функция ответа не может быть вызвана, т.к. ответ не отправляется из background.js
	{
		document.querySelector('#fades').style.display = 'inline'
		document.querySelector('#guild').style.display = 'inline'
		document.querySelector('#mercenary').innerHTML = 'jhg'
	}
)


Так вот, вся проблема заключается в том, что в background.js сначала нужно послать запрос, получить ответ, покопаться в ответе, и только потом отправить ответ на сообщение в maps.js.

Aetae 07.11.2016 20:42

*!*
-                GetHttpRequest(request.href, {rid: request.rid})
*/!*
+                GetHttpRequest(request.href, {rid: request.rid, response: sendResponse});

*!*
-                chrome.tabs.query // Вроде это какое - то событие открытия(или получения) вкладок?
                (
                    {active: true, currentWindow: true}, // Х.з
                    function(tabs)
                    {
                        chrome.tabs.sendMessage // Это то, что отправляет ответное сообщение
                        (
                            tabs[0].id, // Х.з, наверное идентификатор вкладки, куда отправить?
                            {greeting: "hello"}, // Это я так понял и есть ответ?
                            function(response) // А это вообще не нужно вроде...
                            {
                                console.log(response.farewell);
                            }
                        )
                    }
                )
*/!*
+                e.data.response(str);

Артист 07.11.2016 21:33

Не получается получить текст ответа.

Сделал так, только передал строку с идентификатором:
В background.js в обработчике запроса:
e.data.response({value: str})


В maps.js:
chrome.runtime.sendMessage
(
	{id: 6, href: 'http://www.site.ru/bla-bla.php', rid: 3},
	function(response)
	{
		alert('ответ пришел\n' + response.value)
	}
)


Что - то ругается:
Цитата:

Error in event handler for (unknown): TypeError: Cannot read property 'value' of undefined
at chrome-extension://gmiiicnncmloicakdbhhdnclnbebgeik/maps.js:152:38

Aetae 07.11.2016 21:44

chrome.runtime.onMessage.addListener // Отлов сообщений
(
    function(request, sender, sendResponse)
    {
        switch(request.id) // Это типа идентификатор сообщений
        {
            case 2: // GET запрос
            {
                GetHttpRequest(request.href, {rid: request.rid, response: sendResponse})
                break
            }
        }
        *!*return true;*/!*
    }
)
Цитата:

Note: The sendResponse callback is only valid if used synchronously, or if the event handler returns true to indicate that it will respond asynchronously. The sendMessage function's callback will be invoked automatically if no handlers return true or if the sendResponse callback is garbage-collected.
Ненавижу WebExtensions. Мерзость. :-E

Артист 07.11.2016 22:16

Спасибо ))
Всё работает.

Артист 07.11.2016 22:47

Блин, только что всё работало, и вдруг стало выдавать ошибку в background.js (e.data.response({value: str})):

Цитата:

Uncaught TypeError: Cannot read property 'response' of undefined(…)
Ничего не менял, только из XMLHttpRequest ответа нужный текст копировал и записал в str...


background.js:

function GetHttpRequest(href, arg)
{
	var xhr = new XMLHttpRequest()
	xhr.withCredentials = true
	xhr.onreadystatechange = function(e)
	{
		e.data = arg
		ProcessRequestChange.apply(this, arguments)
	}
	xhr.open('GET', href, true)
	xhr.send(null)
}
function ProcessRequestChange(e)
{
	var xhr = this

	if(xhr.readyState != 4) return
	if(xhr.status == 200)
	{
		var html = xhr.responseText
		
		switch(e.data.rid)
		{
			/*-------*/
			case 3: // Гильдия наёмников
			{
				if(html.indexOf('возвращайся с победой') > -1 || (html.indexOf('у нас нет сейчас заданий') > -1 && html.indexOf('Вы получаете') < 0)) break

				var s = html.indexOf('align=left rowspan=2>') + 21
				var e = html.indexOf('</td>', s)
				var str = html.substring(s, e)
				
				e.data.response({value: str})
				break
			}
			/*-------*/
			case 0: break // Без обработки
		}
	}
}
chrome.runtime.onMessage.addListener
(
	function(request, sender, sendResponse)
	{
		switch(request.id)
		{
			/*-------*/
			case 6: // Гн 
			{
				GetHttpRequest(request.href, {rid: request.rid, response: sendResponse})
				return true
				break
			}
			/*-------*/
		}
		return false
	}
)


maps.js:

chrome.runtime.sendMessage
(
	{id: 6, href: 'http://www.site.ru/bla-bla.php', rid: 3},
	function(response)
	{
		//alert('ответ пришел\n' + response.value)
		document.querySelector('#fades').style.display = 'inline'
		document.querySelector('#guild').style.display = 'inline'
		document.querySelector('#mercenary').innerHTML = response.value
	}
)

Артист 07.11.2016 22:55

А вот так всё работает:
//var s = html.indexOf('align=left rowspan=2>') + 21
//var e = html.indexOf('</td>', s)
var str = 'errfsdf'//html.substring(s, e)

Aetae 07.11.2016 22:57

Вот эта строчка:
var e = html.indexOf('</td>', s)
тут вы переназначаете переменную "e", соответственно "e.data" уже ничего не содержит.)

Артист 07.11.2016 23:04

От блин, невнимательность, спасибо ))

Артист 09.11.2016 20:40

Вложений: 1
Блин, задолбала уже эта ошибка:
Цитата:

Error in event handler for (unknown): TypeError: Cannot read property 'value' of undefined.
Если у chrome.runtime.sendMessage назначена функция(в которую ответ приходит), то она всегда что ли будет вызываться?

Просто я сделал одну фигню всплывающим окном(вставил часть другой страницы), через localStorage убрал лишние запросы на сайт...

Вложение 3343

Вот это всё равно вызывается:
chrome.runtime.sendMessage
(
	{id: 6, href: 'http://www.site.ru/bla-bla.php', rid: 3},
	function(response)
	{
		alert('ответ')
		document.querySelector('#fades').style.display = 'inline'
		document.querySelector('#guild').style.display = 'inline'
		document.querySelector('#mercenary').innerHTML = response.value
	}
)

А это обработчик(ну или прослушиватель, как его там правильно) этого сообщения.
Тут всё нормально с return'ами break'ами? Просто я не привык к этой дикости в свитче...
chrome.runtime.onMessage.addListener
(
	function(request, sender, sendResponse)
	{
		switch(request.id)
		{
			case 4: // Получить значение localStorage
			{
				var sid = request.sid
				sendResponse({sid: sid, value: localStorage[sid]})
				break
			}
			case 6: // Обработчик 
			{
				var l = localStorage['mercenary_guild']

				if(l != undefined && l > parseInt(+ new Date() / 1000)) break

				alert('запрос')
				GetHttpRequest(request.href, {rid: request.rid, response: sendResponse})
				return true
				break
			}
		}
		return false
	}
)


Когда срабатывает это условие:
if(l != undefined && l > parseInt(+ new Date() / 1000)) break
Появляется ошибка. Я понял, что нет параметра value в ответе(он вообще пустой).

Не понятно какого хрена он вообще приходит, ведь там нет sendResponse()...

Если всё так и должно работать, можно хотя бы как - то проверить, что ответ пустой?


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