在JavaScript中为所有HTTP请求添加自定义标头

11

我想在ASP.Net Web Form应用程序的每个http调用中添加自定义标头(Bearer令牌)。

根据以下链接的建议,我添加了发送附加标头到服务器的代码,但没有成功。

如何拦截所有http请求,包括表单提交

如何更改请求的标头?

<script>
    (function() { 
        (function (open) {
            XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
                console.log("Adding header");
                open.call(this, method, url, async, user, password);
                this.setRequestHeader("X-Hello", "There " + new Date());
            };
        })(XMLHttpRequest.prototype.open);
    })();
</script>

并且

<script>
    (function() { 
        (function (send) {
            XMLHttpRequest.prototype.send = function (data) {
                console.log("Adding header");
                this.setRequestHeader("X-Hello", "There");
                send.call(this, data);
            };
        })(XMLHttpRequest.prototype.send);
    })();
</script>

我知道这个解决方案本应只适用于POST请求(但实际上并没有)。我可以看到每次POST请求的console.log,但是在服务器端从未看到“X-Hello”头。

使用service worker的冗长解决方案失败了:

return Promise.resolve(new Request(data.url, data));

"构建 'Request' 失败:无法使用模式为 'navigate' 且 RequestInit 不为空的 Request 构建请求。"

3个回答

9

尝试这个:

XMLHttpRequest.prototype.open = (function(open) {
  return function(method,url,async) {
    open.apply(this,arguments);
    this.setRequestHeader('customHeader1', 'someValue');
    this.setRequestHeader('customHeader2', 'someOtherValue');
    };
})(XMLHttpRequest.prototype.open);

3
尽管这段代码可能提供了问题的解决方案,但最好添加上下文来说明它是如何运作的以及为什么要这样做。这可以帮助未来的用户学习并最终将这些知识应用到他们自己的代码中。当代码被解释清楚时,你也有可能获得用户的积极反馈/赞同。 - Amit Verma

6

一种解决方法是使用服务工作者。然而,这种方法并不受所有浏览器的支持,所以请注意你的受众。 通过使用服务工作者,你可以拦截所有经过浏览器的网络请求。但是,浏览器只允许您为与当前源相关的 URL 发送自定义标头。考虑到这一点,这里是一段代码示例:

//This is the fetch event listener
self.addEventListener("fetch", (event) => {
    var currentUrl = new URL(event.request.url);
    if (currentUrl.origin === location.origin){
        var newRequest = new Request(event.request, {
            mode: "cors",
            credentials: "same-origin",
            headers: {
                YOUR_CUSTOM_HEADER_NAME: YOUR_CUSTOM_HEADER_VALUE,
            }
        });
        event.respondWith(fetch(newRequest));
    }
    else {
        event.respondWith(fetch(event.request));
    }
});

同时,如果您使用常量、变量来存储标头的值和名称,则浏览器将以变量名称(小写)作为标头名称(而不是其值)。


1
你可以在方括号中加入变量名 { [foo]: var },以使用变量内的值作为键,而不是 foo。 - run_the_race
这对于在浏览器中运行的客户端有效,对吗?但是你能分享一种类似于服务器端的跟踪出站http调用的方法吗?例如从express.js开始? - Ayush Tiwari

1

你需要实例化XMLHttpRequest才能使用它。

var x = new XMLHttpRequest();
x.open("GET","http://some.url");
x.setRequestHeader("X-Hello","There");
x.send();

你不会直接使用 Request …… 它是由 现代的 fetch(..) API 内部创建的。

fetch("http://some.url",{ method:"GET", headers: { "X-Hello": "There" }})
.then(function onRes(res){
   if (res && res.ok) {
      // ..
   }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接