Javascript 用于传递标题信息的Navigator.sendBeacon()

Javascript 用于传递标题信息的Navigator.sendBeacon(),javascript,w3c,Javascript,W3c,我使用的是与服务器通信,但问题是我们需要传递一些头信息,因为有一个过滤器可以识别请求来自有效源 有人能帮忙吗 谢谢。在搜索此问题的答案后,我发现要使用navigator传递标题,我们需要传递blob对象 例如 var headers = {type: 'application/json'}; var blob = new Blob(request, headers); navigator.sendBeacon('url/to/send', blob); @Vipul Panth提供了一些有用的

我使用的是与服务器通信,但问题是我们需要传递一些头信息,因为有一个过滤器可以识别请求来自有效源

有人能帮忙吗


谢谢。

在搜索此问题的答案后,我发现要使用navigator传递标题,我们需要传递blob对象

例如

var headers = {type: 'application/json'};
var blob = new Blob(request, headers);
navigator.sendBeacon('url/to/send', blob);

@Vipul Panth提供了一些有用的信息,但我想提供一些更完整的细节

首先,请注意并非所有浏览器都支持
navigator.sendBeacon
。有关此功能以及当前支持的浏览器的更多详细信息,请参阅

您确实创建了一个blob来提供标题。以下是一个例子:

window.onunload = function () {
  let body = {
    id,
    email
  };
  let headers = {
    type: 'application/json'
  };
  let blob = new Blob([JSON.stringify(body)], headers);
  navigator.sendBeacon('url', blob);
});
navigator.sendBeacon
将发送一个POST请求,其内容类型请求头设置为
headers.Type
中的任何内容。这似乎是您可以在信标中设置的唯一标题,根据:

sendBeacon方法不提供自定义请求方法、提供自定义请求头或更改请求和响应的其他处理属性的功能。对于此类请求,需要非默认设置的应用程序应使用keepalive标志设置为true的[FETCH]API

我能够观察到这是如何进行的。

如以下所述:

提取对象的字节流(transmittedData)和内容类型(contentType)

提取是如何执行的

我收集的是提取传输数据的内容类型,并将其设置为HTTP请求的内容类型

1) 如果发送Blob对象,则内容类型将成为Blob的类型

2) 如果发送FormData对象,则内容类型将变为多部分/表单数据

3) 如果发送了URLSearchParams对象,则内容类型将变为application/x-www-form-urlencoded

4) 如果发送普通字符串,则内容类型将变为文本/普通


用于实现不同对象的Javascript代码

如果您使用Chrome并试图设置内容类型标题,则可能会由于安全限制而出现一些问题:

Uncaught DomeException:未能在“Navigator”上执行“sendBeacon”:暂时禁用了类型不是内容类型请求标头的任何CORS safelisted值的Blob的sendBeacon()。看见http://crbug.com/490015 详情请参阅。

请参见

,因为sendBeacon(..)方法不允许对标题进行操作,所以我将它们作为普通字段添加到表单中:

    const formData = new FormData();
    formData.append('authorization', myAuthService.getCachedToken());
    navigator.sendBeacon(myURL, formData);
然后,在主机端,我添加了一个简单的中间件类(.Net),它捕获没有头的POST请求,并从主体复制它们:

    public class AuthMiddleware
    {
        ...
        ...
        public async Task Invoke(HttpContext context)
        {
            string authHeader = context.Request.Headers["Authorization"];
            if (authHeader == null && context.Request.Method=="POST")
            {
                context.Request.Headers["Authorization"] = string.Format("Bearer {0}",
                    context.Request.Form["authorization"].ToString());
            }

            await _next.Invoke(context);
        }
    }

作为答案发布,因为我不允许在答案下发布评论:

对于Chrome,navigator.sendBeacon为非CORS安全列表类型发送Blob的问题已在Chrome版本81中修复,因此现在应该可以安全使用。


对于IE,卸载事件中的另一种选择是使用同步ajax请求,因为IE不支持sendBeacon,但在我的例子中支持同步ajax调用。

您的意思是将
新blob
大写,使其成为
新blob
?还有什么是
请求
?您能举出您的任何来源吗?我所说的请求是在浏览器关闭时需要发送的票证数据列表以及一个安全标头,以便服务器可以将其识别为授权请求。是的,您完全正确,因为这是一种试验性方法,仅在最新的浏览器(如)中可用chrome v39。如果我错了,请纠正我,但是keepalive for fetch甚至还没有在chrome中实现。不幸的是,这是不允许的,并将抛出一个错误,由于安全原因,从Chrome59。参见:3)在Chrome中不起作用参见:内容类型仍然是
text/plain;charset=UTF-8
您需要在其他中间件之前添加中间件