You're sending JSON:
return res.status(200).json(imgProcessed)
That means you're sending text, not binary data.
You probably wanted to send just the data:
return res.status(200).send(imgProcessed)
// --------------------^^^^
I'm assuming imgProcessed is a Buffer; if not you want to make it one. See the Express.js documentation for send. (It will handle sending the Content-Type: application/octet-stream header for you when you give it a Buffer.)
Please visit this answer https://stackoverflow.com/a/12776856/16315663 to retrieve GZIP data from the response.
Assuming, You have already retrieved full data as UInt8Array.
You just need the UInt8Array as String
const jsonString = Buffer.from(dataAsU8Array).toString('utf8')
const parsedData = JSON.parse(jsonString)
console.log(parsedData)
Edit
Here is what worked for me
const {request} = require("https")
const zlib = require("zlib")
const parseGzip = (gzipBuffer) => new Promise((resolve, reject) =>{
zlib.gunzip(gzipBuffer, (err, buffer) => {
if (err) {
reject(err)
return
}
resolve(buffer)
})
})
const fetchJson = (url) => new Promise((resolve, reject) => {
const r = request(url)
r.on("response", (response) => {
if (response.statusCode !== 200) {
reject(new Error(`${response.statusCode} ${response.statusMessage}`))
return
}
const responseBufferChunks = []
response.on("data", (data) => {
console.log(data.length);
responseBufferChunks.push(data)
})
response.on("end", async () => {
const responseBuffer = Buffer.concat(responseBufferChunks)
const unzippedBuffer = await parseGzip(responseBuffer)
resolve(JSON.parse(unzippedBuffer.toString()))
})
})
r.end()
})
fetchJson("https://wiki.mozilla.org/images/f/ff/Example.json.gz")
.then((result) => {
console.log(result)
})
.catch((e) => {
console.log(e)
})
Thank you, I actually just tried this approach and I get the following error:
SyntaxError: JSON Parse error: Unexpected identifier "x"
But I managed to print the data in text format using the below function:
getFinancialReports = (options, callback) => {
// buffer to store the streamed decompression
var buffer = [];
https
.get(options, function (res) {
// pipe the response into the gunzip to decompress
var gunzip = zlib.createGunzip();
res.pipe(gunzip);
gunzip
.on("data", function (data) {
// decompression chunk ready, add it to the buffer
buffer.push(data.toString());
})
.on("end", function () {
// response and decompression complete, join the buffer and return
callback(null, buffer.join(""));
})
.on("error", function (e) {
callback(e);
});
})
.on("error", function (e) {
callback(e);
});
};
Now I would need to pass this into a JSON object.
I've been able to write to stdout using the fs phantomjs module, thus being able to write as binary:
var fs = require('fs');
var stream = fs.open('/dev/stdout', 'wb');
stream.write(String.fromCharCode(128));
stream.flush();
It is still pretty slow for large volume of data, for some reason.
The only sane way of printing to the console is using console.log(). The drawback is that it inserts a newline everytime you call it, so you can't just print every character separately. You have to build a string and print it afterwards. As you noted, you can convert every byte to char with String.fromCharCode().
Also, functions like Uint8ClampedArray.prototype.join() are not yet implemented.
var a = new Uint8ClampedArray([37, 38, 39]);
console.log([].map.call(a, function(v){
return String.fromCharCode(v);
}).join());
Note that Uint8ClampedArray is not available in PhantomJS 1.x.
console.log() doesn't work in binary mode, so it will split characters above the 127 code point into two bytes when printed. This happens only when printing. You can check with
String.fromCharCode(147).length; // 1
If you are willing to write a file, you can use the fs module to write it in binary:
var a = new Uint8ClampedArray([37, 38, 39]),
fs = require('fs');
var b = [].map.call(a, function(v){
return String.fromCharCode(v);
}).join("");
fs.write("img.dat", b, "wb");