ruskar
@ruskar
Conflict Intelligence Team

Как осуществить вызов синхронного XMLHttpRequest изнутри расширения (extension) Google Chrome?

Пишу своё первое расширение под Google Chrome и застопорился на одном, казалось бы, простом моменте. Суть расширения такова:
1. перехватываем попытку обращения к mysite.com;
2. кроссдоменным синхронным запросом к нашему собственному сервису на api.service.com запрашиваем какой адрес хоста вместо mysite.com надо подставить;
3. меняем хост mysite.com в запросе пользователя на полученный адрес хоста и выполняем запрос.

Файл manifest.json:
{
	"name": "MyFirstChromeExtension",
	"version": "0.1",
	"description": "Description of my extension",
	"permissions": ["webRequest", "webRequestBlocking", "cookies",
					"*://mysite.com/*", "*://api.service.com/*"],
	"background": {
		"scripts": ["background.js"]
	},

	"manifest_version": 2
}


Файл background.js:
var newlink = false;
function setLink() {
	var req = new XMLHttpRequest();
	// открываем синхронный запрос к API нашего сервиса
	req.open('GET', 'http://api.service.com', false);
	req.onload = function() {
		// API в заголовках ответа, в "кастомном" заголовке
		// Link-Url присылает нам нужную ссылку
		// + одновременно при этом сервер ставит кукисы "newlink"
		// для домена api.service.com, в которых сохраняет
		// полученный адрес ссылки
		newlink = this.getResponseHeader('Link-Url');
	};
	req.send(null);
	return newlink;
}
function getLink() {
	// смотрим, есть ли у нас в кукисах сохранённый адрес нужной ссылки
	// Если есть - берём его. В противном случае выполняем запрос к API сервиса
	chrome.cookies.get({url:'http://api.service.com', name:'newlink'}, function(cook) {
		if ( ! cook)
			return setLink();
		else
			return cook.value;
	});
}
chrome.webRequest.onBeforeRequest.addListener(
	function(info) {
		// отключаем перехватывание запросов к нашему API
		if(info.url.indexOf('api.service.com') != -1)
			return {cancel:false};
		
		var link = getLink();

		return {redirectUrl: info.url.replace(/mysite.com/i, link)};
	},
	// filters
	{
		urls: [
			"*://mysite.com/*",
			"*://api.service.com/*"
		]
	},
	// extraInfoSpec
	["blocking"]
);


Всё прекрасно получается, кроме одного момента: callback-функция для onBeforeRequest отрабатывает, возвращает redirectUrl раньше, чем функция getLink() возвращает нужное значение ссылки. В итоге адрес хоста mysite.com подменяется на undefined. И это несмотря на то, что в функции setLink() объект XMLHttpRequest открывает синхронное соединение.

Где моя ошибка, подскажите?

API всё возвращает правильно, заголовок Access-Control-Allow-Origin: * в ответе стоит, кукисы ставятся нормально - с этим проблем нет. Т.е. при второй и последующих попытках обращения к mysite.com значение ссылки берётся уже из кукисов и всё отрабатывает как надо, хост подменяется.

Описание объекта webRequest
Описание объекта cookies
  • Вопрос задан
  • 4090 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
28 апр. 2024, в 20:09
9000 руб./за проект
28 апр. 2024, в 19:54
2000 руб./за проект
28 апр. 2024, в 19:54
5000 руб./за проект