我在Node.js(MERN堆栈)项目中使用Axios从服务器请求数据。请求的结果是一个较大的JSON字符串,但是过早地被切断。奇怪的是,如果我重新启动后端服务器和前端服务器,有时它只能工作一次。控制台输出看起来像这样(有人请内联它,我还没有这个声誉...):
https://i.imgur.com/9zts7IZ.png
在后端:
<script type="vertexShader" id="vertexShader">
#version 300 es
in vec3 position;
in vec4 color;
out vec4 fcolor;
void main () {
gl_Position = vec4(position, 1.0);
fcolor = color;
}
</script>
<script type="fragmentShader" id="fragmentShader">
#version 300 es
precision mediump float;
in vec4 fcolor;
out vec4 finalColor;
void main () {
finalColor = vec4(fcolor);
}
</script>
var gl, canvas;
gl = initWebGLCanvas('canvas');
var program = getProgram('vertexShader', 'fragmentShader', true);
document.getElementById('numOfGrids').oninput = function () {
clearCanvas(gl);
this.value = this.value || 1;
this.value = this.value >= 0 ? this.value : 0;
var gridVertices = createGridVerticesBuffer(this.value || 1);
enableVerticesToPickBinaryDataWithinGPU(program, 'position', 'color');
fetchDataFromGPUAndRenderToCanvas({
positionIndex : gl.positionIndex,
vertices : gridVertices,
positionSize : 3,
stride : 7,
colorIndex : gl.colorIndex,
colorSize : 4,
positionoffset : 0,
colorOffset : 3,
startIndexToDraw : 0,
numOfComponents : 6
}, gl);
};
var r = [1.0, 0.0, 0.0, 1.0];
var g = [0.0, 1.0, 0.0, 1.0];
var b = [0.0, 0.0, 1.0, 1.0];
var z = 0.0;
var createGridVerticesBuffer = (gridsRequested) => {
var vertices = [
1.0, -1.0, z, r[0], r[1], r[2], r[3],
-1.0, 1.0, z, g[0], g[1], g[2], g[3],
-1.0, -1.0, z, b[0], b[1], b[2], b[3],
1.0, -1.0, z, r[0], r[1], r[2], r[3],
-1.0, 1.0, z, g[0], g[1], g[2], g[3],
1.0, 1.0, z, b[0], b[1], b[2], b[3]];
var vertexArray = [];
var factor = 2.0/gridsRequested;
var areaRequired = -1.0 + factor;
vertices[21] = vertices[0] = areaRequired;
vertices[15] = vertices[1] = -areaRequired;
vertices[22] = -areaRequired;
vertices[35] = areaRequired;
vertices[36] = vertices[8];
vertexArray.push(vertices);
var lastVertices = vertices.slice();
var processX = true;
for (var i = 1; i <= gridsRequested * gridsRequested - 1; i++) {
var arr = lastVertices.slice();
if (processX) {
arr[21] = arr[0] = lastVertices[0] + factor;
arr[28] = arr[7] = lastVertices[35];
arr[8] = lastVertices[36];
arr[14] = lastVertices[0];
arr[15] = lastVertices[1];
arr[35] = lastVertices[35] + factor;
} else {
arr[22] = arr[1] = lastVertices[1] - factor;
arr[29] = arr[8] = lastVertices[8] - factor;
arr[15] = lastVertices[15] - factor;
arr[36] = lastVertices[36] - factor;
}
vertexArray.push(arr);
if ((i + 1) % gridsRequested === 0) {
lastVertices = vertexArray[i + 1 - gridsRequested];
processX = false;
} else {
processX = true;
lastVertices = arr;
}
}
return createBuffers(gl, vertexArray, true);
};
在前端:
app.route("/exercise/run").post(checkAuth ,function (req, res) {
// doing some stuff (start child_process to run java program which returns json object)
res.status(200).json(jsonObj);
}
我有点希望每次都能正常工作,但事实并非如此。我想知道是否正确或过早地关闭了连接,但是我已经搜索了几个小时,却没有找到有效的修复程序。
我也尝试将其分块发送(甚至因为我已经知道json的大小而不必流传输),所以甚至认为它不是要注意的事情,但是那也不起作用。完全相同的错误,有时它会起作用(通常是当我重新启动所有功能时),大多数时候它会被切断。
在后端:
let options = {
timeout: 10000,
maxContentLength: 1000000000,
};
Axios.post('http://localhost:4000/exercise/run', data, options)
.then(response => {
if (response.status === 200) {
let output = Buffer.from(response.data).toString();
let json = JSON.parse(output); // this fails because it is cut short
console.log(json);
}
})
.catch(function (error) {
console.error(error);
});
在前端:
function splitAndSendJSON(res, json) {
const CHUNCK_SIZE = 2000;
let jsonString = JSON.stringify(json);
let dataArray = [];
for (var i = 0; i < jsonString.length; i += CHUNCK_SIZE) {
dataArray.push(jsonString.slice(i, i + CHUNCK_SIZE));
console.log(i);
}
res.writeHead(200, {
'Content-Type': 'text/plain; charset=utf8',
'Transfer-Encoding': 'chunked'
});
// res.write("[");
for (var i = 0; i < dataArray.length-1; i++) {
res.write(dataArray[i]);
}
res.write(dataArray[dataArray.length-1]);
// res.write("]");
res.end();
}
答案 0 :(得分:0)
因此,显然这根本不是HTTP问题。我正在使用child_process生成另一个进程,并且该进程似乎将输出分块。由于HTTP响应只能发送一次数据,因此它仅发送第一个块并停止。现在,我将流程数据推送到一个数组中,然后将其发送给客户端。
res.dataArray = [];
child.stdout.on('data', function (data) {
console.log("stdout");
if (data) {
res.dataArray.push(data);
}
});
child.on('close', function (exitCode) {
console.log("close");
console.log(exitCode);
res.status(200).json(res.dataArray);
});
我必须将列表中的Buffer对象合并为一个Buffer对象,然后将其解析为JSON。
let buffers = [];
for (let buffer of response.data) {
buffers.push(Buffer.from(buffer));
}
let finalBuffer = Buffer.concat(buffers);
let json = JSON.parse(finalBuffer.toString());
我可能已经在服务器端执行了此操作,因此客户端不必执行此工作,而是已经收到了最终的json对象。