如何解决 Server-sent Events 中 CORS 跨域问题

前言

Server-sent Events(SSE)是一项 HTML5 技术,用于在客户端和服务器之间建立一种持久的连接,服务器可以通过该连接向客户端发送新数据,从而实现实时通信。但是,由于浏览器的安全限制,SSE 只允许与同源的服务器通信,即不能跨域发送数据,这给跨域场景下的实时通信带来了一定的困扰。

因此,本文将介绍如何解决 Server-sent Events 中 CORS 跨域问题,以实现在跨域场景下使用 SSE 进行实时通信。

解决方案

1. 后端设置响应头

在 SSE 中,当客户端发送请求与服务器建立连接时,服务器需要设置响应头 Access-Control-Allow-Origin,以允许客户端跨域访问。

示例代码:

res.writeHead(200, {
  'Content-Type': 'text/event-stream',
  'Cache-Control': 'no-cache',
  'Access-Control-Allow-Origin': '*'
});

其中,Access-Control-Allow-Origin 的值为 * 表示允许任意跨域访问。如有必要,也可以将其设置为指定的域名。

2. 前端使用代理服务器

在跨域场景下,可以使用代理服务器将请求转发到后端,然后在代理服务器上进行 SSE 通信。这样,就可以绕过浏览器的安全限制,实现跨域通信。

示例代码:

// 使用 axios 发送跨域请求
axios.get('/api/sse', {
  responseType: 'stream',
  headers: {
    'Accept': 'text/event-stream'
  }
})
.then(function (response) {
  // 创建 SSE 对象
  let sse = new EventSource('/proxy/sse');

  // 监听 SSE 事件
  sse.onmessage = function (event) {
    console.log(event.data);
  };
})
.catch(function (error) {
  console.log(error);
});

其中,/api/sse 是原始请求的地址,/proxy/sse 是代理服务器的地址。在代理服务器上,需要通过 SSE 连接到原始请求的服务器,然后将数据转发到客户端。

3. 前端使用 WebSocket

除了 SSE,WebSocket 也可以实现跨域实时通信。与 SSE 不同的是,WebSocket 是基于 TCP 连接的,可以发送任意类型的数据。

示例代码:

// 创建 WebSocket 对象
let ws = new WebSocket('ws://localhost:3000');

// 监听 WebSocket 事件
ws.onopen = function () {
  console.log('WebSocket connected!');
};

ws.onmessage = function (event) {
  console.log(event.data);
};

ws.onclose = function () {
  console.log('WebSocket disconnected!');
};

ws.onerror = function (event) {
  console.log(event);
};

在跨域场景下,WebSocket 也需要后端设置 Access-Control-Allow-Origin 响应头,以允许跨域访问。

总结

本文介绍了解决 Server-sent Events 中 CORS 跨域问题的三种方案,包括后端设置响应头、前端使用代理服务器和前端使用 WebSocket。其中,后端设置响应头是最简单的方案,可以直接在后端进行配置;使用代理服务器可以绕过浏览器限制,但增加了复杂度;WebSocket 具有更高的灵活性,但需要服务端和客户端都支持。根据实际需求及场景选择合适的方案,可以更好地实现跨域场景下的实时通信。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659132c5eb4cecbf2d66b997


纠错反馈