答案 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.
答案 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 发送数据。
您可以尝试使用纯文本发送数据。但不要忘记来自后端的解析文本。