📜  HTTP 标头 | Sec-WebSocket-Accept(1)

📅  最后修改于: 2023-12-03 15:31:19.902000             🧑  作者: Mango

HTTP 标头 | Sec-WebSocket-Accept

简介

Sec-WebSocket-Accept 标头是 WebSocket 浏览器请求的响应之一。它是 WebSocket 握手过程中服务器根据握手请求计算出的一个值。

使用方式

在 WebSocket 连接握手过程中,客户端会发送一个包含 Sec-WebSocket-Key 标头的握手请求,该标头的值是一个随机的字符串。服务器需要将该值与一个固定的字符串 "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" 拼接后计算出一个 SHA-1 摘要,并将结果采用 Base64 编码后赋给 Sec-WebSocket-Accept 标头并返回给客户端。

const crypto = require('crypto');

const MAGIC_STRING = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';

function createWebSocketAccept(key) {
    const hash = crypto.createHash('sha1');
    hash.update(key + MAGIC_STRING, 'binary');
    return hash.digest('base64');
}
示例

这里我们将使用 Node.js 的 http 模块实现一个简单的 WebSocket 服务器,演示 Sec-WebSocket-Accept 标头的使用。

const http = require('http');
const crypto = require('crypto');

const PORT = process.env.PORT || 8080;
const MAGIC_STRING = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';

function createWebSocketAccept(key) {
    const hash = crypto.createHash('sha1');
    hash.update(key + MAGIC_STRING, 'binary');
    return hash.digest('base64');
}

const server = http.createServer((req, res) => {
    if (req.url === '/ws') {
        const key = req.headers['sec-websocket-key'];
        const accept = createWebSocketAccept(key);
        res.writeHead(101, {
            'Upgrade': 'websocket',
            'Connection': 'Upgrade',
            'Sec-WebSocket-Accept': accept,
        });
        const socket = req.socket;
        socket.write('\x81\x01\x48'); // 发送一个包含一个字节的数据帧
        socket.end();
    } else {
        res.writeHead(404);
        res.end();
    }
});

server.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});
注意事项
  • Sec-WebSocket-Accept 标头应该只在响应握手请求时使用,不应该出现在后续的 WebSocket 数据帧中。