【问题标题】:How to unpatch a method in a Javascript object? Specifically XMLHttpRequest.open如何取消修补 Javascript 对象中的方法?特别是 XMLHttpRequest.open
【发布时间】:2020-08-06 18:04:27
【问题描述】:

我们有一个 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 请求中默认包含授权标头,从而在每次有人需要发出请求时节省一行额外的代码。

这件事的一个缺点是我们有一些用例,我们希望向需要自己的授权标头的外部 api(跨域)发出请求。默认情况下添加另一个授权标头没有帮助,因为它附加了标头而不是替换它。

补丁在 index.js 文件中完成,该文件是加载整个 React UI 的主文件。

有没有办法仍然可以调用未打补丁的方法,或者以某种方式能够替换 XMLHttpRequest 中的 Authorization 标头。

显然,XMLHttpRequest 似乎没有办法取消设置或替换标头。它只有一种称为setRequestHeaders 的方法来附加它们。

我想了几个不同的方向来解决这个问题。对其中任何一个或替代方案的任何建议都会有所帮助。

1 - 尝试使用原始参考 (original) 修补 (patch2) 已修补的 (patch1) 方法,并在使用后将其修补回 patch1 方法。不确定是否可以从 patch1 方法中获取原始的引用。

2 - 将 index.js 中的原始引用保存到某个全局上下文中,并在进行外部调用时将 XMLHttpRequest.prototype.open 暂时更改为原始引用并将其重置。

3 - 找到取消设置和/或替换标题的方法。

4 - 任何其他不使用下面的 XMLHttpRequest 的 HTTP 请求库。我不确定是否存在。我猜像 fetch、axios、jquery ajax 之类的所有库都必须在下面使用 XMLHttpRequest。

【问题讨论】:

  • 我会使用xhrPrevOpen 变量,但这是一个非常 X/Y 问题
  • xhrPrevOpen 是一个全局变量,还是这个代码在使它成为本地的 IIFE 中?

标签: javascript xmlhttprequest http-headers closures monkeypatching


【解决方案1】:

情况有点不幸,理想的解决方案是不首先修补方法,而是更新需要添加该标头的各种调用,以便它们这样做(可能通过调用包装函数)。

如果你做不到:

我很想像这样编辑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; // <====

...然后在您不想修补open 的情况下使用__rawopen__ 而不是open

再次:只有当你真的、真的无法撤消 open 的那个糟糕的补丁时。


  • 任何其他不使用下面的 XMLHttpRequest 的 HTTP 请求库。我不确定是否存在。我猜像 fetch、axios、jquery ajax 之类的所有库都必须在下面使用 XMLHttpRequest。

我不会假设在fetch 的情况下,只要它是浏览器提供的本机版本。我希望XMLHttpRequestfetch 都使用相同的底层内部功能,而不是fetch 字面意思 使用暴露的XMLHttpRequest 用户态代码可以使用。您可能想检查您的目标浏览器,看看fetch 是否真的受到您的代码对XMLHttpRequest.prototype.open 所做的更改的影响。我怀疑不是,这会给你另一种解决问题的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    • 2017-02-12
    • 1970-01-01
    • 2017-11-30
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多