Webextension: Как прозрачно изменить XMLHttpRequests - PullRequest
0 голосов
/ 04 апреля 2020

Моя цель

… - иметь веб-расширение (пока что Firefox), которое перехватывает и изменяет XMLHttpRequest проблемы сайта максимально прозрачно. В лучшем случае это расширение не обнаруживается сайтом даже при явном поиске. Например, я хочу иметь возможность автоматически редактировать / заменять критически важные данные перед их отправкой или обеспечивать кэширование больших изображений, несмотря на то, что исходная страница явно отключает это.

Оригинальный подход

Использование фоновый скрипт и browser.webRequest с blocking для перехвата всех запросов.

browser.webRequest.onBeforeRequest.addListener(
  modifySend,
  {
    urls: ["<all_urls>"],
  },
  ["blocking", "requestBody"]
);

browser.webRequest.onResponseStarted.addListener(
  modifyReceive,
  {
    urls: ["<all_urls>"],
  },
  ["blocking", "responseHeaders"]
);

Это работает в некоторой степени. Хотя я могу просматривать все запросы, изменение содержимого отправлений (POST) невозможно, и (некоторые?) Измененные заголовки полученных игнорируются Firefox. Например, мне не удалось перезаписать cache-control, исходное значение все еще действовало.

Сценарии содержимого

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

Вопросы

Как правильно перехватить и изменить XMLHttpRequests? Возможно ли это даже в той степени, в которой я хочу? И как расширение: как предоставить большие двоичные объекты данных в качестве ответа, например, если я делаю свое собственное кэширование, когда я не могу убедить браузер игнорировать заголовки «без кэширования»?

1 Ответ

0 голосов
/ 01 мая 2020

В итоге я использовал два отдельных подхода. Один для предоставления больших двоичных объектов данных и один для XMLHttpRequest перехвата.

BLOB-объектов содержимого

Кажется, что самый простой вариант - предоставить данные как web_accessible_resources, а затем использовать фоновый скрипт расширения для принудительного перенаправления:

function serveLocally(details)
{
  const localRes = browser.runtime.getManifest().web_accessible_resources;
  let ret = {};

  localRes.forEach(file => {
    if (details.url.endsWith(file))
    {
      ret.redirectUrl = browser.runtime.getURL(file);
    }
  });
  return ret;
}

Перехват

Здесь я использую скрипт контента, который внедряет скрипт в страницу . Внедренный скрипт перезаписывает функцию open XMLHttpRequest:

содержимого. js

function injectJS(file) {

  let D = document;
  let s = D.createElement('script');

  s.type = "text/javascript";
  s.src = browser.runtime.getURL(file);
  s.onload = function() {
    s.parentNode.removeChild(s);
  };

  (D.head || D.documentElement).appendChild(s);
}

injectJS("inject.js");

inject. js (отдельный файл и среди web_accessible_resources)

let realOpen = window.XMLHttpRequest.prototype.open;

window.XMLHttpRequest.prototype.open = function() {
  let method = arguments[0];
  let url = arguments[1];
  ...  
  realOpen.apply(this, arguments);
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...