简体   繁体   中英

Passing JSON from node.js to PHP via HTTP

I have a Node.js system which reads binary file contents, adds metadata to them and uploads the generated data to a PHP-based server. However, doing JSON.stringify on the node.js end and reading data back on the PHP side results in data being corrupted.

Note that I'm not declaring content type as JSON, but rather sending everything as POST data - the system has other uses, so I want to keep everything uniform.

Node.js side:

const chunks = [];
fs
    .createReadStream(GR.dataFolder + 'output/' + file, {
        start: from,
        end: from + size - 1,
        autoClose: true
    })
    .on('data', function(chunk) {
        chunks.push(chunk);
    })
    .on('end', function() {
        let data = Buffer.concat(chunks);
        let hash = crypto.createHash('md5').update(data).digest('hex');
        processUploadFilePart(hash, data);
    })
;

function processUploadFilePart(hash, data) {
    let payload = {
        hash: hash,
        data: data.toString('binary'),
    };

    // verify - this results in a correct hash, so node.js does not lose data in JSON.stringify
    let tmp = JSON.stringify(payload);
    tmp = JSON.parse(tmp);
    let hashed = crypto.createHash('md5').update(Buffer.from(tmp.data, 'binary')).digest('hex');
    console.log(hashed);

    request
        .post({
            url: server,
            body: JSON.stringify(payload),
            encoding: null, // does not seem to have any effect
            }, function(err, response, body) {
                // PHP responds with a different data hash
            }
        )
    ;
}

PHP side:

$request = file_get_contents('php://input');
$json = json_decode($request, true);
$md5 = md5($json['data']);
if ($md5 !== $json['hash']) {
    $this->output['error'] = 'hash mismatch';
}

Found the issue in my own code: request body was a string as resulting from JSON.stringify(payload) ; it got automatically doubleencoded into UTF-8. Changing to a buffer and explicitly specifying binary encoding fixes doubleencoding:

body: Buffer.from(JSON.stringify(payload), 'binary'),

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM