📅  最后修改于: 2023-12-03 15:31:19.902000             🧑  作者: Mango
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 数据帧中。