SSE 对跨域通信的支持及应用实践
SSE(Server Sent Events)是一种在浏览器和服务器之间进行实时数据传输的机制,它通过 HTTP 协议进行通信,采用长轮询(long polling)的方式从服务器端获取数据。SSE 方式的数据传输是单向的,只能由服务器端向客户端发送数据,而客户端不能向服务器端发送数据,因此更适合用于一些实时性要求不高、需要从服务器端获取数据的场景。本文将介绍 SSE 在跨域通信方面的应用实践。
一、SSE 的使用
1.1 服务器端的实现
服务器端需要使用 SseEmitter 类来实现 SSE 的传输。该类提供了向浏览器端发送数据的方法 send(),以及注册和取消注册事件监听器的方法 onCompletion() 和 onError()。
下面是一个简单的 Java 代码示例:
-- -------------------- ---- ------- ----------------- - ------------------ -------- - ---------------------------------- ------ ---------- --------------- ------ ----------- - ---------- ------- - --- ------------- -------- -------- - -- -- - --- - --- ---- - - -- - - --- ---- - ------------------- - - - - -------- ------------------- -- ------------------ - - ----- ---------- -- - ----------------------------- ------- - ------------------- -- --- ------------------------- ------ -------- -展开代码
上述代码中,我们实现了一个 /stream-emitter 的接口,该接口返回一个 SseEmitter 对象。然后我们在该对象上发送数据,模拟了服务端每一秒钟向客户端发送一条数据的过程。
1.2 客户端的实现
客户端需要使用 EventSource 类来实现 SSE 的接收。该类的构造方法接收一个 URL 参数,该 URL 参数指向服务器端 SSE 接口的地址。在接收到数据时,客户端将自动触发指定的事件处理函数。
下面是一个简单的 JavaScript 代码示例:
const eventSource = new EventSource('/stream-emitter'); eventSource.onmessage = (event) => { console.log(event.data); };
上述代码中,我们实例化了一个 EventSource 对象,该对象引用了 /stream-emitter 接口。当服务器端向客户端发送数据时,客户端将自动调用 onmessage 事件处理函数,将接收到的数据打印到控制台上。
二、SSE 的跨域支持
在默认情况下,SSE 支持的是同源策略下的通信,即服务器和客户端必须处于同一个域名下。如果我们想要在跨域的情况下使用 SSE,需要在服务器端和客户端分别进行相关配置。
2.1 服务器端的跨域配置
在 Spring Boot 中,我们可以使用 @CrossOrigin 注解来进行跨域配置。修改我们刚刚的例子,增加 @CrossOrigin 注解即可实现从任意源访问 SSE 接口。
@GetMapping(value = "/stream-emitter", produces = MediaType.TEXT_EVENT_STREAM_VALUE) @CrossOrigin public SseEmitter streamEmitter() throws IOException { // ... }
2.2 客户端的跨域配置
在客户端中,我们需要在实例化 EventSource 对象时,指定 withCredentials 参数为 true。同时,服务器端需要在响应头中增加 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials 参数,允许跨域访问,否则客户端将无法接收到数据。
下面是一个简单的 JavaScript 跨域配置代码示例:
const eventSource = new EventSource('/stream-emitter'); eventSource.withCredentials = true; eventSource.onmessage = (event) => { console.log(event.data); };
2.3 对跨域通信的应用实践
在实际项目中,我们可以通过 SSE 来实现一些实时性不高、但需要实时获取数据的功能,如实时日志追踪、实时告警推送等等。例如我们可以在服务端实现一个实时日志监控的接口,将服务器端的日志实时推送到客户端,便于项目组快速定位问题。
-- -------------------- ---- ------- ----------------- - --------------- -------- - ---------------------------------- ------------ ------ ---------- ------------ ------ ----------- - ------ ---- - -------------------- -- ----------------- ---------- ------- - --- ------------- -------- -------- - -- -- - --- - ------- ------- - ------------------------------- -- - - ------ -------------- -- - --- ------------------ --------------------------------------------- ------ ----- ----- ------ - -------------- -- ----- - ------------------- - - ---- - -------- - - ----- ---------- -- - ----------------------------- ------- - ------------------- -- --- ------------------------- ------ -------- -展开代码
上述代码中,我们实现了一个 /log-emitter 的接口,该接口将实时监控 /var/log/messages 文件的变化,并将变化的内容实时推送给客户端。
在客户端中,实现相应的接口调用即可接收到实时的日志内容。
const eventSource = new EventSource('/log-emitter'); eventSource.withCredentials = true; eventSource.onmessage = (event) => { console.log(event.data); };
以上就是 SSE 对跨域通信的支持及应用实践的详细介绍,希望能够对前端开发人员有所帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67c297e7314edc2684bf72a6