我正在使用 uWebSocket.js 并尝试从 API 获取有效负载。我检查了其与路线相关的官方GitHub网站。
我检查并实施了其中解释的所有方法,效果很好。但是,我面临着从 post 方法获取 body 数据的问题。
我尝试的是...
let app = uWS
./*SSL*/App()
.post('/login', (res, req) => {
console.log(req.body);
res.end(JSON.stringify({ message: 'Nothing to see here!' }));
})
.ws('/*', {
/* Options */
compression: uWS.SHARED_COMPRESSOR,
maxPayloadLength: 16 * 1024 * 1024,
idleTimeout: 10 * 4,
maxBackpressure: 1024,
open: (ws) => {
/* Let this client listen to topic "broadcast" */
},
message: (ws, message, isBinary) => {
},
drain: (ws) => { },
close: (ws, code, message) => {
}
})
.listen(port, (token) => {
if (token) {
console.log('Listening to port ' + port);
} else {
console.log('Failed to listen to port ' + port);
}
});
https://github.com/uNetworking/uWebSockets/issues/805#issuecomment-451800768
这是一个例子
.post("/short", (res, req) => {
res
.onData((data) => {
const stringed = handleArrayBuffer(data);
console.log("stringed received", stringed);
})
res.write("Great knowing you");
res.writeStatus("200OK");
res.end();
})
上面收到的数据将以数组缓冲区的形式进入,因此您可能希望将其解码为这样的字符串
export const handleArrayBuffer = (message: ArrayBuffer | string) => {
if (message instanceof ArrayBuffer) {
const decoder = new TextDecoder();
return decoder.decode(message);
}
return message;
};
const parseBody = (res: uWS.HttpResponse): Promise<{ [key: string]: any } | undefined> => {
return new Promise((resolve, reject) => {
let buffer: Buffer = Buffer.alloc(0);
let totalSize = 0;
res.onData((ab, isLast) => {
try {
if (res.aborted) {
reject(new Error('Request aborted'));
return;
}
if(ab.byteLength > 0) { // I found some non-last onData with 0 byte length
const copy = copyArrayBuffer(ab); // Immediately copy the ArrayBuffer into a Buffer, every return of onData neuters the ArrayBuffer
totalSize += copy.byteLength;
buffer = Buffer.concat([buffer, Buffer.from(copy)]);
}
if (totalSize > MAX_BODY_SIZE) { // define your allowed max size if it applies to you
reject(new Error('Request body too large: max 4MB allowed'));
return;
}
if (isLast) {
// If this is the last chunk, process the final buffer
// Convert the buffer to a string and parse it as JSON
// this will fail if the buffer doesn't contain a valid JSON (e.g. when buffer.byteLength = 0)
const resolveValue = JSON.parse(buffer.toString());
resolve(resolveValue);
}
} catch (err: any) {
reject(new Error(`Failed to parse JSON: ${err.message}`));
}
});
});
};
const useBodyParser = (res: uWS.HttpResponse, req: uWS.HttpRequest, next: (body?: any) => void) => {
// I haven't checked what happens when there's no body (onData ever called). For my usecase, there's always a json body for put and post requests, hence this implementation.
if (req.getMethod() === 'post' || req.getMethod() === 'put') {
parseBody(res).then(body => {
next(body);
}).catch(err => {
res.cork(() => {
res.writeStatus('500 Internal Server Error').end(`Body parsing error: ${err}`);
});
});
} else {
next();
}
};
uWs.App().any('/*', async (res: uWS.HttpResponse, req: uWS.HttpRequest) => {
useBodyParser(res, req, (body: { [p: string]: any } | undefined) => {
// process request here
});
});