从HTTP响应(Axios)缩短了JSON

时间:2019-04-06 13:23:25

标签: node.js http axios

我在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();
}

1 个答案:

答案 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对象。