avoid uint8array object conversion in axios,nodejs - javascript

I am trying to send uint8array in Axios payload in POST by doing this
app.post('/upload',upload.single('file') ,async function(req, res){
var fileString = fs.readFileSync('./uploads/file.jpeg')
var u8 = new Uint8Array(fileString);
console.log(u8);
try {
const payload = {
"binData":u8
}
const response = await axios.post("https://xyz/uploadservice",payload)
res.status(200).send({"success":response})
} catch (error) {
res.status(400).send({"error":error})
}
the xyz api endpoint expects binData in bytearray format,but its going in objects format like
binData : {"0":"23","1","255".....}
but it expects like this, binData : [23,255,.....]

Related

Return a CSV File from Flask to Angular Client

I have an app which runs an Angular Frontend and Flask Backend. I have created a button that trigger a API call to Flask that queries my database and returns a dataframe (df) in a CSV format.
I believe I have coded the Flask part correctly as I can't see any errors in the logs. However, I do get an error appearing on the client side which is:
SyntaxError: Unexpected token '', ""... is not valid JSON
I suspect its because my subscribing of the data is done incorrect, but I am unsure of what needs to happen
Angular (When the Download Button is clicked, this is triggered)
fullDownload() {
let responseData: any;
const date = this.selectedDate;
const id= this.selectedId;
this.seriveFile.getFullData(date, id).subscribe(
data => {
responseData = new Blob([data], {type: 'text/csv'})
const url = window.URL.createObjectURL(responseData);
window.open(url);
},
error => {this.errorMessage = error.error.error;
}
);
}
Angular (The service it calls)
public getFullData(value, id) {
let params = new HttpParams();
params = params.append('date', value);
params = params.append('id', id);
return this.http.get<any>(`${this.baseAPIURL}/api/example/download-data`, {params, responseType:"blob" as "json"});
}
Flask
resp = make_response(df.to_csv(index=False))
resp.headers["Content-Disposition"] = "attachment; filename=export.csv"
resp.headers["Content-Type"] = "text/csv"
return resp
This should download the file:
fullDownload() {
let responseData: any;
const date = this.selectedDate;
const id = this.selectedId;
this.seriveFile.getFullData(date, id).subscribe(
data => {
const filename = 'csv.csv';
const a = document.createElement('a');
a.href = window.URL.createObjectURL(data);
a.download = filename;
a.click();
},
error => {
this.errorMessage = error.error.error;
}
);
}

How do I receive multiple JSON objects and use each one seperately?

I am trying to receive JSON objects via a websocket server. And I receive one JSON object every second that I want to be able to use each one separately as it gives a status on whether someone is active or not. However, whenever I try and store all the JSON's into a data structure only the final JSON I receive will be stored the others get deleted.
So my question is: is there a way to store JSON into a data structure whilst receiving it?
This is the JSON I receive looks something like this:
{"studentNum":"21127985","active":false,"currentScore":0}
here is the code for receiving the json from the server:
const WebSocket = require('ws');
// const serverAddress = "ws://127.0.0.1:5000";
const serverAddress = ' *SERVER NAME*';
const ws = new WebSocket(serverAddress, {
headers: {
"user-agent": "Mozilla"
}
});
ws.on('open', function () {
});
ws.on('message', function (msg) {
fs = require('fs')
console.log(msg.toString())
var obj = JSON.parse(msg);
/* convert buff to string
const json = JSON.parse(file.toString())
json.push(msg);*/
var writerStream = fs.createWriteStream('output.json')
writerStream.write(msg, 'UTF-8')
writerStream.end();
writerStream.on('finish', function () {
});
writerStream.on('error', function (err) {
console.log(err.stack);
});
});
you can put fs outside of your WS message callback
const WebSocket = require('ws');
fs = require('fs');
var writerStream = fs.createWriteStream('output.json')
const serverAddress = "ws://127.0.0.1:5000";
const serverAddress = ' *SERVER NAME*';
const ws = new WebSocket(serverAddress, {
headers: {
"user-agent": "Mozilla"
}
});
ws.on('open', function () {
});
ws.on('message', function (msg) {
writerStream.write(msg, 'UTF-8')
writerStream.on('error', function (err) {
console.log(err.stack);
});
});
Or alternatively you can write file in chunks i.e. store 10 messages in an array and write it using fs.appendFile function.

Node Send Files as URL

I have an image file in the server side, and would like to send this image to the client side to display it in the web. It seems like URL.createObjectURL can only be used in a DOM, it sounds impossible to convert the image file to URL in expressJS, or is there any other way to return the image as URL from server side?
I am now trying to send the image buffer and try to use URL.createObjectURL on the client side. It seems like res containing a bunch of weird character string, and I tried to create a Blob, but the image does not render on the web at all.
fetch(`http://localhost:9000/foo`)
.then((res) => res.text())
.then((res) => {
var test = new Blob([res], { type: "image/jpeg" });
props.setImageSrc((prev) => [
...prev,
URL.createObjectURL(test),
]);
});
router.get("/", function (req, res, next) {
var buffer = fs.readFileSync("/Users/foo/bar/image1.jpeg");
var bufferBase64 = new Buffer.from(buffer);
res.send(bufferBase64);
});
Below are part of the res I got on the client side
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz�������������������
Use this function to convert the base64 buffer string to blob
const b64toblob = (string, fileType) => {
const byteCharacters = atob(string);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
return new Blob([byteArray], { type: `image/${fileType}` });
};
Receive base64 buffer string from server
fetch(`http://localhost:9000/foo`)
.then((res) => res.text())
.then((res) => {
const blob = b64toblob(buffer, "jpeg");
props.setImageSrc((prev) => [
...prev,
URL.createObjectURL(blob),
]);
});
In server, read the file and convert to base64 buffer
router.get("/", function (req, res, next) {
var buffer = fs.readFileSync("/Users/foo/bar/image1.jpeg");
var bufferBase64 = new Buffer.from(buffer);
res.send(bufferBase64.toString("base64"));
});

How to send Data in chunks from server (node.js) to client(react.js)?

I ended up with having a Server who provides pictures in base64 format. The Problem is when I want to send an array of base64 Images they are to huge.
I want to send the Array in little chunks to the frontend.
I use Sequelize to retrieve the data from the database.
Does someone has an Idea How to do it.
Thats How my endpoint looks until now:
router.get('/download', async (req, res, next) => {
try {
const getAllStoneData = await StoneData.findAll();
const convertBlobToString = getAllStoneData.map((oneStone) => {
const getBuffer = oneStone.dataValues.blobImage;
const convertToString = getBuffer.toString('utf8');
const copyOneStone = {
...oneStone.dataValues,
blobImage: convertToString,
};
return copyOneStone;
});
let chunk = [];
while (convertBlobToString.length > 0) {
chunk = convertBlobToString.splice(0, 1);
res.write(chunk);
}
res.end();
} catch (error) {
res.status(400).send({ error });
}
});
When I run this I get the Error of
"UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client"

Apple IAP Receipt Validation Node.js

I'm trying to use Node.js from here for my IAP Receipt Validation, but it always returns error on a server's log: "The data in the receipt-data property was malformed."
Can someone help me to properly send base64 string to Node.js and to decode it there as same base64 string for receipt validation? I have zero experience with javascript and been trying to make this simple code work for two days now, to no avail.
Here is my Swift code:
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
let receiptString = receiptData.base64EncodedString(options: [])
var request = URLRequest(url: URL(string: "https://us-central1-calendizer-6a849.cloudfunctions.net/receiptValidation")!)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
// attach receipt data to a request
request.httpBody = receiptString.data(using: .utf8)
print("httpBody: \(request.httpBody?.base64EncodedString())")
Logs.log("✉️ Receipt Validation -> sending request ...")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
...
}
Here is my Node.js code (Firebase Cloud Functions):
const functions = require('firebase-functions');
var iap = require('in-app-purchase');
exports.receiptValidation = functions.https.onRequest((request, response) => {
var receipt_try1 = request.body
var receipt_try2 = request.body.toString('base64');
var receipt_try3 = JSON.stringify(receipt);
var receipt_try4 = new Buffer(request.body.toString(), 'base64')
console.log("receipt: " + receipt_try1)
iap.config({
applePassword: 'my shared key',
test: true
});
iap.setup(function (error) {
if (error) {
console.log("Setup error:" + error) // Failed to validate
}
iap.validate(iap.APPLE, receipt_try1, function (error, appleResponse) {
if (error)
{
console.log("Validation error:" + error) // Failed to validate
}
if (iap.isValidated(appleResponse)) {
console.log("successful validation" + appleResponse)
response.send(appleResponse)
}
});
});
});
did it using json:
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
let receiptBase64String = receiptData.base64EncodedString(options: [])
//.replacingOccurrences(of: "+", with: "%2B")
// prepare json data
let json: [String: Any] = ["receipt_string": receiptBase64String]
let jsonData = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)
// create post request
var request = URLRequest(url: URL(string: "https://us-central1-calendizer-6a849.cloudfunctions.net/receiptValidation")!)
//request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = jsonData
and in Node.js simply:
var receipt = request.body.receipt_string

Categories