【问题标题】:Safari Server Sent Event (SSE) Infinte LoopSafari 服务器发送事件 (SSE) 无限循环
【发布时间】:2018-02-27 19:07:07
【问题描述】:

我在 Safari 9 和 Safari 10 中遇到服务器发送事件 (SSE) 问题。SSE 连接打开,立即关闭,然后在无限循环中重新连接。

这是客户端代码:

var events = new EventSource("/stream/events")

这些是 http 响应标头:

> GET /stream/events HTTP/1.1
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Access-Control-Allow-Origin: *
< Cache-Control: no-cache
< Connection: keep-alive
< Content-Type: text/event-stream
< Expires: Thu, 01 Jan 1970 00:00:00 GMT
< Last-Modified: Tue, 19 Sep 2017 05:28:22 GMT
< Strict-Transport-Security: max-age=31536000
< X-Accel-Buffering: no
< X-Content-Type-Options: nosniff
< X-Frame-Options: DENY
< X-Xss-Protection: 1; mode=block
< Date: Tue, 19 Sep 2017 05:28:22 GMT
< Transfer-Encoding: chunked

一些补充说明:

  • 我在 Chrome 和 Firefox 中测试过,无法重复
  • 我在 Safari 中测试过没有 https 并且无法重复
  • 我在 Safari 中测试过使用 https 并且可以重复
  • https 证书是使用 Lets Encrypt 自动生成的
  • 后端服务器用 Go 编写,默认使用 http/2

我只能在 Safari 中使用 https 重复这一事实很有趣。因此,我想知道 SSE 和 https 是否存在任何已知问题,或者我可能在此处配置错误或遗漏了其他任何问题。

编辑

我已隔离问题并发现与协议相关。启用 http2 协议后,我能够重现此问题。在服务器上禁用 http2 后,我将无法再重现此问题。

我使用了以下服务器补丁来验证:

--- before.go   2017-09-19 13:31:45.668891000 -0400
+++ after.go    2017-09-19 13:31:55.100891000 -0400
@@ -2,6 +2,6 @@
            Addr: ":443",
            TLSConfig: &tls.Config{
                GetCertificate: manager.GetCertificate,
-               NextProtos:     []string{"h2", "http/1.1"},
+               NextProtos:     []string{"http/1.1"},
            },
        }

【问题讨论】:

  • 你能显示 Safari 发送的标题吗?我的猜测是在 GET 请求之前发送了 HEAD 或 OPTIONS 请求,并且您的后端脚本没有处理它。 (http/2 的角度很有趣。)(我发布的是评论,而不是答案,因为目前这是一个相当疯狂的猜测,但请参阅我的书的第 9 章,带有 HTML5 SSE 的数据推送应用程序,其中 Safari 是行为不同的浏览器。)
  • 感谢您的提问。服务器配置为回复所有 OPTIONS 和 HEAD 请求,但是,根据服务器日志,我们都没有收到。我禁用了 http2,并且我的应用程序一切正常,所以至少我有一个临时的解决方法。我每晚在 Safari 9 / 10 / 11 / webkit 中进行测试,所以在这一点上,我认为创建 webkit 错误报告可能是下一步。
  • 是否可以查看 Safari 以查看它发送的请求和标头? IE。就像您使用 Chrome 和 Firefox 获得的 Web 开发人员屏幕(现在内置)。看看 Safari 的事件视图是否与您的服务器日志相匹配将会很有趣。
  • 网络选项卡仅显示请求的单个 GET 条目。

标签: javascript safari eventsource


【解决方案1】:

我敢打赌,Safari javascript 控制台充满了:

[Error] Failed to load resource: The operation couldnt be completed. Protocol error

这很可能是一个协议错误。 http/2 的section 8.1.2.2 表示

端点不得生成包含特定连接头字段的 HTTP/2 消息;任何包含特定于连接的标头字段的消息都必须被视为格式错误。

我无法确定这是您的问题,因为我没有看到您的 http/2 尝试的 HTTP 标头,但是许多 http/2 实现选择仍然发送 Connection: Keep-Alive 标头,而几个用户代理,包括Safari 和 curl,决定对此事严格要求。

更新

我应该补充一点,错误的标头,很可能是标准的“连接:保持活动”之一,可以由任何服务器端组件(通常是应用程序的 SSE 服务器端组件)设置,而不是容器本身.我打赌容器应该在 http/2 中过滤它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多