Как распаковать метод в Javascript объект? В частности, XMLHttpRequest.open - PullRequest
0 голосов
/ 23 апреля 2020

У нас есть приложение React, в котором кто-то исправил метод XMLHttpRequest.open примерно так:

const token = ....
let xhrPrevOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (...a) {
    xhrPrevOpen.apply(this, [ ...a ]);
    this.setRequestHeader('Authorization', `Bearer ${token}`);
};

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

Недостатком этой вещи является то, что у нас есть несколько случаев использования, когда мы хотим отправлять запросы на внешние apis (междоменные), которые требуют собственных заголовков авторизации. Добавление другого заголовка авторизации по умолчанию не помогает, так как он добавляет заголовок вместо его замены.

Исправление выполняется в файле index. js, который является основным файлом, который загружает весь пользовательский интерфейс реакции.

Есть ли способ по-прежнему вызывать непатченный метод или каким-либо образом заменить заголовок Authorization в XMLHttpRequest.

По-видимому, не похоже, что XMLHttpRequest можно отключить или заменить заголовки. У него есть только один метод с именем setRequestHeaders, чтобы добавить их.

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

1 - Попробуйте пропатчить (patch2) уже пропатченный (patch1) метод с исходной ссылкой (оригинал) и после использования пропатчить его обратно к метку patch1 , Не уверен, возможно ли получить ссылку на оригинал из метода patch1.

2 - сохранить исходную ссылку из индекса. js в некотором глобальном контексте и на мгновение изменить XMLHttpRequest.prototype.open на orginal при выполнении внешнего вызова и сбросе его обратно.

3 - найдите способ отменить и / или заменить заголовок.

4 - любая другая библиотека HTTP-запросов, которая не использует нижний XMLHttpRequest , Я не уверен, что существует. Я предполагаю, что все библиотеки, такие как fetch, ax ios, jquery ajax должны использовать XMLHttpRequest внизу.

1 Ответ

1 голос
/ 23 апреля 2020

Ситуация немного прискорбна, и в идеале решение состоит в том, чтобы не исправлять метод в первую очередь , а вместо этого обновлять различные вызовы, которым нужно добавить этот заголовок, чтобы они делали это (возможно, путем вызова функция-обертка).

Если вы не можете сделать это:

Я бы хотел отредактировать index.js примерно так:

const token = ....
let xhrPrevOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function (...a) {
    xhrPrevOpen.apply(this, [ ...a ]);
    this.setRequestHeader('Authorization', `Bearer ${token}`);
};
XMLHttpRequest.prototype.__rawopen__ = xhrPrevOpen; // <====

... затем используйте __rawopen__ вместо open в тех случаях, когда вы не хотите исправлять open.

Опять : только если вы действительно, действительно не могу отменить этот ужасный патч open.


  • Любая другая библиотека HTTP-запросов, которая не использует нижестоящий XMLHttpRequest. Я не уверен, что существует. Я предполагаю, что все библиотеки, такие как fetch, ax ios, jquery ajax должны использовать XMLHttpRequest внизу.

Я бы не предположил, что в случае fetch, при условии, что это родная версия, предоставленная браузером. Я ожидал бы, что и XMLHttpRequest, и fetch будут использовать одни и те же внутренние функции, а не fetch в буквальном смысле с использованием незащищенного XMLHttpRequest, с которым может быть изменен пользовательский код. Возможно, вы захотите проверить в своих целевых браузерах, чтобы увидеть, действительно ли на fetch влияет изменение вашего кода на XMLHttpRequest.prototype.open. Я подозреваю, что это не так, что даст вам другой способ решения проблемы.

...