Пишу своё первое расширение под 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