#javascript #node.js #stream #node-https
#javascript #node.js #поток #узел-https
Вопрос:
Я запрашиваю сервер rest у nodejs с помощью модуля запроса nodejs. Я хочу отменить поток, если размер входящих данных превышает допустимый предел. цель здесь — убедиться, что моя сеть не заблокирована.
Мой пример кода выглядит следующим образом;
var http = require("http");
async function httpRequest({
host,
method,
port,
path
} = params, data) {
if (method.toUpperCase() === "GET") {
let query = "";
data = JSON.parse(data);
for (var key in data) {
if (data.hasOwnProperty(key)) {
let value = data[key];
console.log(key " -> " value);
query = query
.concat("amp;")
.concat(key)
.concat("=")
.concat(value);
}
}
if (query) {
query = "?".concat(query.substring(1));
}
path = encodeURI(path.concat(query));
console.log("path : " path);
}
var opts = {
hostname: host,
port: port,
path: path,
method: method,
timeout: 30 * 1000,
headers: {
"Content-Type": "application/json"
}
};
return new Promise(function (resolve, reject) {
const req = http.request(opts, function (response) {
console.log("Status Code : " response.statusCode);
if (response.statusCode < 200 || response.statusCode >= 300) {
req.end();
return reject("Fetch data failed = " response.statusCode);
}
var str = "";
response.on("data", function (chunk) {
console.log("chunk : " chunk);
str = chunk;
if (str.length > 256) {
req.abort();
reject(
new Error(
"The size of the incoming data is larger than the allowable limit."
)
);
}
});
response.on("end", function () {
console.log("n Result from web service : ", str);
try {
let jsonData = JSON.parse(str);
if (jsonData.status) {
if (jsonData.status.toLowerCase === "success") {
if (!("result" in jsonData)) {
reject("Json Structure Error");
}
} else if (jsonData.status.toLowerCase === "error") {
if (!jsonData.error) {
reject("Json Structure Error");
}
}
resolve(jsonData);
} else {
reject("Json Structure Error");
}
} catch (error) {
reject("Response json error : " error);
}
});
});
if (method.toUpperCase() !== "GET" amp;amp; data) {
req.write(data);
}
//req bitti
req.on("timeout", function () {
console.log("timeout! " opts.timeout / 1000 " seconds expired");
req.abort();
});
req.on("error", function (err) {
console.log("Error : " err);
if (err.code === "ECONNRESET") {
req.abort();
console.log("Timeout occurs : " err);
reject(new Error("Timeout occurs : " err));
} else if (err.code === "ENOTFOUND") {
req.abort();
console.log("Address cannot be reachable : " err);
reject(new Error("Address cannot be reachable : " err));
} else {
req.abort();
reject(new Error(err));
}
});
req.end();
});
}
let data = JSON.stringify({
username: "monetrum",
password: "123456",
name: "Loremipsumdolorsitamet,consecteturadipiscingelit"
".Aeneaninaliquamodio,egetfac"
});
let params = {
host: "127.0.0.1",
method: "GET",
port: 3010,
path: "/login"
};
httpRequest(params, data);
Пока все хорошо.Но есть проблема.Я контролирую входящие данные.Разрешенный размер данных не должен превышать 256 байт.Но первая выборка блока больше допустимого размера.Так что мой контроль размера — это ерунда.Есть ли способ справиться с этим.Возможно ли ограничить размер блока. Заранее спасибо.
Ответ №1:
Событие ‘readable’
Вы хотите использовать readable
событие вместо data
event:
var byteCount = 0;
var chunkSize = 32;
var maxBytes = 256;
req.on('readable', function () {
var chunks = [];
var data;
while(true) {
data = this.read(chunkSize);
if (!data) { break; }
byteCount = data.byteLength;
if (byteCount > maxBytes) {
req.abort();
break;
}
chunks.push(data);
}
// do something with chunks
});
req.on('abort', function () {
// do something to handle the error
});
Поскольку ваш вопрос очень специфичен, я сделал пример немного более общим, так что, надеюсь, другие тоже смогут извлечь из него информацию.
Смотрите https://nodejs.org/api/stream.html#stream_event_readable
Однако…
Сети все равно
Однако вы собираетесь получить больше данных, чем это. Размер TCP-пакета составляет 64 кб. Через негигабитный Ethernet, при котором MTU усекается до 1500 байт (1,5 кбайт).
Вы ничего не можете сделать, чтобы предотвратить сетевую активность, кроме закрытия соединения, и вы не можете получить менее 1,5 тыс. данных за событие data, если только не отправляется менее 1,5 тыс. данных (или возникают сумасшедшие проблемы с сетью, которые вы не можете контролировать).t
P.S.
Я бы рекомендовал вам использовать редактор кода, такой как VSCode. Очень сложно читать код, который содержит сочетания табуляций и пробелов и разные блоки на разных уровнях. Он предложит плагины, которые помогут вам раньше обнаруживать ошибки и переформатировать ваш код, чтобы другим (и вам самим) было легче его читать.
Комментарии:
1. Большое спасибо за ваш ответ. Я не знал свойства readable. Я попытаюсь работать.
2. И спасибо также за ваше предложение. Я уже использую VSCode и Prettier — Code formatter. Но я не понимаю, как это форматируется.
3. Некоторые примечания, вы должны добавить читаемый прослушиватель к разрешению , а не к запросу uest. Кроме того, req.abort() не рекомендуется, используйте req.destroy() .