Navigator.sendBeacon()传递头信息

时间:2016-11-10 08:56:51

标签: javascript w3c

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

有人可以提供帮助吗?

感谢。

7 个答案:

答案 0 :(得分:13)

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

首先,请注意并非所有浏览器都支持https。请参阅MDN documentation

,详细了解此功能以及当前支持的浏览器

您确实创建了一个blob来提供标头。这是一个例子:

navigator.sendBeacon

window.onunload = function () { let body = { id, email }; let headers = { type: 'application/json' }; let blob = new Blob([JSON.stringify(body)], headers); navigator.sendBeacon('url', blob); }); 将发送一个POST请求,其Content-Type请求标头设置为navigator.sendBeacon中的任何内容。根据{{​​3}}:

,这似乎是您可以在信标中设置的唯一标头
  

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

我能够通过这个W3C观察到一些如何发挥作用。

答案 1 :(得分:3)

正如Processing Model of sendBeacon所述:

  

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

如何执行提取是described here

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

1)如果发送了Blob对象,则Content-Type将成为Blob的类型。

2)如果发送了FormData对象,则Content-Type将变为multipart / form-data

3)如果发送了URLSearchParams对象,则Content-Type将变为application / x-www-form-urlencoded

4)如果发送了普通字符串,则Content-Type将变为text / plain

用于实现不同对象的{Javascript代码can be found here

答案 2 :(得分:3)

如果您使用的是Chrome,并且尝试设置content-type标头,则由于安全限制,您可能会遇到一些问题:

Uncaught DOMException: Failed to execute 'sendBeacon' on 'Navigator': sendBeacon() with a Blob whose type is not any of the CORS-safelisted values for the Content-Type request header is disabled temporarily. See http://crbug.com/490015 for details.

See this thread

答案 3 :(得分:0)

在搜索此问题的答案后,我发现要使用导航器传递标题,我们需要传递一个blob对象。

例如

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

答案 4 :(得分:0)

由于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);
        }
    }

答案 5 :(得分:0)

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

对于Chrome,navigator.sendBeacon向非CORS安全列表类型发送Blob的问题已在Chrome版本81中修复,因此现在可以安全使用。 https://bugs.chromium.org/p/chromium/issues/detail?id=724929

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

答案 6 :(得分:0)

Chrome 39 出于安全考虑而被禁用后,您将无法使用 JSON 发送数据。

您可以尝试使用纯文本发送数据。但不要忘记来自后端的解析文本。