Server-sent Events(SSE)是一种 Web API,可以在单向连接中从服务器向客户端推送数据流。它允许服务器向客户端推送新的数据,而无需客户端发出请求。与 WebSocket 相比,SSE 更加轻量级,易于实现且更加易于使用。但是,在实际应用中,SSE 可能会遇到跨域访问的问题。本文将详细介绍 SSE 的跨域访问问题以及相应的解决方案,并提供示例代码。
SSE 跨域访问问题
在默认情况下,SSE 可能无法跨域访问,这是出于安全考虑而采取的限制措施。如果浏览器向另一个域名发出 SSE 请求,则会出现以下错误:
EventSource's response has a MIME type (“text/html”) that is not “text/event-stream”.
即 SSE 响应的 MIME 类型不是 text/event-stream
,而是 text/html
。这意味着 SSE 请求返回的不是数据流,而是一个 HTML 页面,因此浏览器无法读取数据流。
解决方案
1. CORS 跨域访问
CORS(Cross-Origin Resource Sharing)是一种跨域访问的标准。它允许服务器在响应头中添加一些特定的字段,告诉浏览器是否允许跨域访问某个资源。在使用 SAE 的用户可以在配置文件中修改响应头即可解决。
添加如下响应头:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET,POST,HEAD,OPTIONS Access-Control-Allow-Headers: Origin,X-Requested-With,Content-Type,Accept
上述响应头会允许所有域名的访问,如果只允许特定域名访问,可以将 *
替换为具体的域名。
2. JSONP 解决跨域访问
JSONP 是一种简单的跨域解决方案。它通过在客户端动态创建一个 script 标签,设置其 src
属性为远程资源的地址,并在该地址后加上一个 callback 参数,该参数是客户端定义的一个函数名。服务器在响应中返回一个用该函数名包裹的 JSON 数据,客户端接收到数据后,执行该函数即可获取数据。
其实,在服务器返回数据时,不仅可以返回 JSON 数据,还可以返回 SSE 数据,这样就可以解决 SSE 跨域访问的问题。以下是一个示例代码:
-- -------------------- ---- ------- -------- -------- - ----------- - ----- -------- - ---- -------------- - --- ------------- - ----- - --------------------- - -------- -- - -- -------------- - ----------- - --- ---------------------- --- ---- - ----- --------------------------------------- -------- ------- - --- ---- - ----------------------- --- ------------- - --------------------------- -- --------------- - ------------------------- - --- ------------------------------------ -------- ------- - --- -------- - ------------------ ------------- - --------- --- ------------------------------------- -------- ------- - -- ----------------- --- ------------------- - -------------------- ----------- - ----- - --- - -- ---------------- - -------- ----------- --------- - ------------------------- - --------- -- --- --- - --- ---------------------------------------------- ----------------- -------- ------ - ------------------ --- --------------
以上示例代码使用了 JSONP 的方式,将 SSE 请求的地址设为 https://www.example.com/sse?callback=?
,其中的 callback=?
就是 JSONP 的语法,浏览器会自动为其生成一个随机的函数名。服务器返回的响应将包含如下内容:
callback({"event":"message","data":"hello world"});
浏览器会自动执行 callback
函数,并传入一个 JSON 对象作为参数,客户端可以根据返回的 event
字段来区分不同的 SSE 数据。
总结
本文介绍了 SSE 的跨域访问问题,并提供了两种解决方案,分别是 CORS 和 JSONP。其中,CORS 是一种标准的跨域解决方案,但需要在服务器端进行配置;JSONP 则是一种简单的跨域解决方案,但需要服务器端支持。根据实际情况选择合适的方案来解决 SSE 跨域访问问题。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/649be11b48841e98948a3759