下面的代码使用sendBeacon方法发送异步HTTP请求,
var data = {
name: 'test',
uniqueId: Math.random()
};
var blob = new Blob([JSON.stringify(data)], {type : 'application/json'});
navigator.sendBeacon('http://example.in/data/post', blob);这段代码已经运行了很长一段时间。目前,由于铬https://bugs.chromium.org/p/chromium/issues/detail?id=490015中的安全问题,我们看到错误“未能在‘Navigator’上执行'sendBeacon‘:使用非CORS类型的Blob的sendBeacon() -安全人员MIME-类型在实验上是不允许的。有关详细信息,请参见 http://crbug.com/490015 。”
在问题解决之前,是否可以通过使用相同的sendBeacon API修改请求头来发送JSON数据?对于依赖于这个API的站点来说,在修复之前继续使用是很有用的。关于使用XHR发布数据的建议并不有用。
发布于 2021-11-23 06:17:22
简短回答:到2021年,已经解决了这个问题,。
Long答案(背景):我在从事时间现场JS开发的某个时候打开了这个问题。它过去在Chrome、Firefox和许多其他浏览器中运行良好。但是,几个月后,我突然跳过了CORS安全列表错误,无法实时地节省现场数据的时间。它迫使我们放弃本地存储,这将导致(N-1)页面浏览量&随后,在每一次用户会话期间,都会出现有损的站点上时间数据,这是一个重要的网络分析指标。我们一直在急切地等待浏览器厂商解决这个问题。这是我们用于捕获直接依赖于sendBeacon() API的实时配置。
<script type="text/javascript">
var Tos;
(function(d, s, id, file) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s);
js.id = id;
js.onload = function() {
// save with XMLHttpRequest (sync=true is blocking approach) or sendBeacon(preferred approach)
var config = {
trackBy: 'seconds',
callback: function(data) {
console.log(data);
// give your endpoint URL/ server-side URL that is going to handle your TOS data which is of POST method. Eg. PHP, nodejs or python URL which saves this data to your DB
var endPointUrl = 'http://localhost:4500/tos'; // replace with your endpoint URL
if (data && data.trackingType) {
if (data.trackingType == 'tos') {
if (Tos.verifyData(data) != 'valid') {
console.log('Data abolished!');
return;
}
}
// make use of sendBeacon if this API is supported by your browser.
if (navigator && typeof navigator.sendBeacon === 'function') {
data.trasferredWith = 'sendBeacon';
var blob = new Blob([JSON.stringify(data)], {type : 'application/json'});
navigator.sendBeacon(endPointUrl, blob);
}
/*else {
// XMLHttpRequest begins..
// XMLHttpRequest with sync=true (blocking approach)
// XMLHttpRequest code block here to post your data
}*/
}
}
};
if (TimeOnSiteTracker) {
Tos = new TimeOnSiteTracker(config);
}
};
js.src = file;fjs.parentNode.insertBefore(js, fjs);
} (document, 'script', 'TimeOnSiteTracker', 'https://cdnjs.cloudflare.com/ajax/libs/timeonsite/1.1.0/timeonsitetracker.min.js'));
</script> 正如您在上面看到的,由于CORS的安全问题,过去几年我们一直在注释sendBeacon()代码块,并且依赖async=false的async=false发布数据,这是阻塞的方法,在许多浏览器上,特别是在移动设备上,这种数据并不十分可靠。
最近,浏览器供应商似乎已经解决了这个问题,sendBeacon() API又回来消费了。我在多个浏览器上进行了测试,它似乎运行得很好。因此,在2021年,此问题被标记为“已解决的”。我希望您添加那些在beforeunload/unload窗口事件中很好地使用版本/年份的设备/浏览器。
发布于 2017-08-10 20:23:25
现在,sendBeacon中的内容类型标头的唯一允许值是:
在我们的项目中,我遇到了类似的问题,最后以‘text/平原;charset=UTF-8’的形式发送数据,并在服务器端读取json内容的流。
客户端:
const blob = new Blob([JSON.stringify(myData)], { type: 'text/plain; charset=UTF-8' });
navigator.sendBeacon(appData.ReleaseSessionUrl, blob);服务器:
using (var reader = new StreamReader(this.Request.InputStream))
{
var jsonData = reader.ReadToEnd();
var sessionData = JsonConvert.DeserializeObject<MyDataType>(jsonData);
}不知道这是否对你有帮助。
https://github.com/GoogleCloudPlatform/stackdriver-errors-js/issues/10
发布于 2019-12-17 12:33:14
请注意,该方法似乎在大多数浏览器上被破坏。这是一个关于这个主题的大数据研究。
https://stackoverflow.com/questions/45274021
复制相似问题