【问题标题】:Navigator.sendBeacon() data size limitsNavigator.sendBeacon() 数据大小限制
【发布时间】:2015-05-13 10:06:12
【问题描述】:

我想使用全新的信标 API。我在网上搜索,但找不到数据,发送数据的大小限制是多少。 在参考文献中,它是针对少量数据的,但我必须知道有多少......

【问题讨论】:

    标签: javascript google-chrome firefox navigator


    【解决方案1】:

    最大大小(如果设置)将取决于用户代理(浏览器或其他)。

    http://www.w3.org/TR/beacon/#sec-sendBeacon-method

    您可以通过创建可变长度的字符串N(从N 的任意高值开始,并使用二进制搜索)轻松地在您的网页中创建data 大小限制的测试,并检查sendBeacon 的返回值(根据规范,当超出用户代理数据限制时,sendBeacon 返回 false)。

    例如,我使用此方法确认在 Windows 7 上的 Chrome 40 中限制为 65536 (2^16)。

    示例代码(没有对n 进行二分搜索):

    var url = 'http://jsfiddle.net?sendbeacon';
    var n = 65536; // sendBeacon limit for Chrome v40 on Windows (2^16)
    
    // this method courtesy of http://stackoverflow.com/questions/14343844/create-a-string-of-variable-length-filled-with-a-repeated-character
    var data = new Array(n+1).join('X'); // generate string of length n
    
    if(!navigator.sendBeacon(url, data))
    {
       alert('data limit reached');
    }
    

    【讨论】:

    • 我做了一个类似于你写的测试。我看到我可以发送一条长消息(比如说 32000 字节),但是我不能发送两次。第二次我弄错了。我重试了一遍——一旦我发送了一条大消息——下一个必须更小。有什么想法吗?
    • 我不知道为什么......但我也看到了。至少对于 Chrome(我已经尝试过),似乎确实有一些机制可能是为了防止使用这种方法来 DOS 服务器?如果我在一个紧密的循环中运行它,它会在 n 的低值处停止(如 33),但如果我在两次测试之间等待几秒钟,我最多可以在 Chrome 中获得 65536。
    • 2021 年 Windows 10 上的 Chrome 91 仍然适用 65536 限制
    【解决方案2】:

    回复Zbun's question in comment

    简而言之,sendBeacon() 请求队列的总字节大小以及单个sendBeacon() 请求的有效负载大小都有限制。

    正如nothingisnecessary 的回答中提到的,W3C spec 说:

    用户代理必须启动设置了 keepalive 标志的提取,这限制了此类请求可以排队的数据量,以确保信标请求能够快速及时地完成。

    这仍然将实际字节大小限制留给每个实现,目前大多数浏览器通常为 64KB。

    同样在一个相关的 GitHub 问题Enforce payload limits via Fetch API #39 中,提到传输中的有效载荷的字节大小是计算在内的,并且有类似的限制。您可以查看 Chromium 的测试文件,以了解 64KB 是 Chromium 的限制,并且与您指出的完全相同的行为(超出限制后的后续请求)是合适的。

    https://chromium.googlesource.com/chromium/src/+/c1a211aa583ade023aca652e9493c01603623aa3/third_party/WebKit/LayoutTests/http/tests/sendbeacon/beacon-allowance-limit.html

    【讨论】:

    • 我看到你提到了keepalive = true的fetch,sendBeacon实现最终会调用fetch吗? sendBeacon 和 fetch 有什么区别吗?
    • @MichalTsadok sendBeaconBeacon API 规范中定义,该规范建立在 fetch standard 之上。 navigator.sendBeacon()window.fetch() 是完全不同的 API,但据我了解,它们在内部使用相同的 fetch 机制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多