NodeJS read file into string without encoding like PHP file_get_contents - javascript

I'm trying to process image and pass image data from a NodeJS app to hit an API wrote in PHP.
I use fs.readFileSync to read the image file (I'm using PNG here). The API only takes string as file content to upload. It seems like PHP file_get_contents doesn't have a specified encoding as I tried mb_detect_encoding($fileContent) and outputs false and the fileContents starts like \x89PNG\r.
I'm using Node v8 and it seems like i have to use some encoding to convert Buffer to string. I tried couple of encoding like base64, binary and the fileContent starts like \xc2\x89PNG\r or \xef\xbf\xbdPNG\r.
What is the equivalent of PHP file_get_contents in NodeJS? How can I get the right format of image data?
Thanks!

If I understood you right, you want to read an image file using nodeJS and send the image as a string to an API which is built using PHP. Have you tried first encoding it to base64 and casting it as string ?
var fs = require('fs');
// read binary data
var png= fs.readFileSync(pathToImageFile);
// convert binary data to base64 encoded string
var imageString = new Buffer(png).toString('base64');
Then send the imageString as a string, hope this helps!

Related

Cannot encode/decode base64 a file using Node on Windows

I am trying to send over HTTP a ZIP file, to achieve that I encode/decode it in Base64. That is not working unfortunately.
I have figured out the issue is actually in the encode/decode itself and was able to isolate and reproduce it.
Consider a simple code which:
Reads a file from the filesystem.
Base64 encodes that file.
Base64 decodes the previously computed base64 string into a binary stream and save it into another file (same identical as original).
const fs = require("fs");
const buffer = fs.readFileSync("C:/users/Public/myzip.zip"); // 1. read
const base64data = buffer.toString("base64"); // 2. encode
fs.writeFileSync("C:/users/Public/myzip2.zip",
new Buffer(base64data, "base64"),
"base64"); // 3. decode + save
The code runs fine (I am on Windows 10), no errors. It successfully reads and writes files. However, file myzip2.zip is written but it cannot be opened: Windows complains it is invalid :(
A bit more context
The reason for this question is the following. I am using Base64 encoding in order to successfully send over a ZIP file from a client to a server.
This code isolates the problem I am having by leaving the networking complexity out of the equation. I need to figure out how to properly encode/decode a file using Base64. Once I can make it work on a single machine, it will work when sending the file.
Why is this basic set of commands not working?

Convert binary / unicode string to image

I am using a library to recieve attachments (image) from salesforce using OAuth and a proxy. Without the library (and the proxy) I am able to the same using XHR, but I have to use the library because I need the proxy.
In chrome debugger I can see image is downloaded fine, but I can't get it to work in my code. Data looks like:
So far methods I have tried:
btoa(unescape(encodeURIComponent(file.body)));- produces a base64 that does not work. decoding it using online tools gives me back the same string.
escape(file.body) - using this as base64 also does not work.
Converting to a blob.
var blob = new Blob([file.body], {type : "image/png"});
urlCreator.createObjectURL(blob);
The url it points to displays nothing, and if I remove {type : "image/png"} the url points to a page displaying same binary string.
Long story short this looks like someone read the image with readAsText() which mangles ("interprets") binary into utf8, instead of utf16. You need to get the server to return the data in arraybuffer or blob format ideally, or even base64, these preserve binary.
Long version with snippet. (those question marks symbols in the snippet show the lost information, compare it to the binary where they are not question marks in utf16):
https://stackoverflow.com/a/56523118/2962797
I would create an <img /> element, equal its src attribute to the image data you received. Now you have the image.
If you want to extract it or convert it to PNG, I would apply this another answer process.

Is file_get_contents in PHP the same as toDataUrl in Javascript?

I want to use an API to compress images. It says the input can as well be a buffer (string with binary), for example:
$sourceData = file_get_contents("unoptimized.jpg");
$resultData = \Tinify\fromBuffer($sourceData)->toBuffer();
In my understanding, they use file_get_contents to create that buffer from a file.
In my case, I already got an canvas image using a React application. To make the API call, I create a data URI, using .toDataURL() looking something like this:
data:image/png;base64,iVBORw0KGgoAAAANSUh... // lots of letters
So can I just use this data URI instead of file_get_contents, because both commands actually do the same in different languages, or is there a difference? Like:
$sourceData = 'data:image/png;base64,iVBORw0KGgoAAAANSUh...'
\Tinify\fromBuffer($sourceData)->toBuffer();
API Reference: https://tinypng.com/developers/reference/php
file_get_contents returns the content of a file as string, and that string exactly represents the content of the file.
.toDataURL() gives you a data url. The data:image/png;base64, part tells that the following data represents a png and that the data is base64 encoded.
To get the same data representation as you get with file_get_content you would need to decode the iVBORw0KGgoAAAANSUh...
So yes, both give you the content of a file, but they don't do that in the same way.
To toBlob on the other hand will return a Buffer containing the data in the same representation as file_get_contents would do.
Assuming you have a PNG file named input.png, the following two pieces of code produce the same result:
Read the image data from the PNG file:
$sourceData = file_get_contents('input.png');
Read the image data from a data: URL generated from the PNG file:
// Generate the 'data:' URL
$url = 'data:image/png;base64,'.base64_encode(file_get_contents('input.png'));
// Read the image data from the 'data:' URL
$sourceData = file_get_contents($url);
The second piece of code works only if fopen wrappers are enabled on the server where the file_get_contents() is executed.
It doesn't make much sense to use the second fragment of code in a single script (because it does a redundant encoding and decoding) but it makes a lot of sense if the encoding and restoring (decoding) happen in different scripts.
They can be part of the same application (the script that encodes the data stores it in the database, the other script loads from the database, restores the image data and uses it) or the decoding could happen in a remote application that sends the data URL over the Internet to be decoded and used by a different application.

Check typeof text data

I have a string like in this link http://pastie.org/private/n7bu5qlknphtyyv5sqla.
I am trying to decode it using different methods
new Uint8Array(encodedString);
and also tried some octal decoders online but no success. Can anyone help me to understand encoding type and how to decode it.
Edit:
Progress: It is a file loaded from client side. Before I was using readAsBinaryString and now I changed it to reader.readAsArrayBuffer(blob); Now I am getting ArrayBuffer and converted it to new Uint8Array(arrayBuffer). It seems now I have some data zipped data.

javascript sendfile binary data to web service

At work we are trying to upload files from a web page to a web service using html 5/javascript in the browser end and C# in the web service. But have some trouble with encoding of some sort.
As for the javascript we get the file's binary data with help from a FileReader.
var file = ... // gets the file from an input
var fileReader = new FileReader();
fileReader.onload = dataRecieved;
fileReader.readAsBinaryString(file);
function dataRecieved() {
// Here we do a normal jquery ajax post with the file data (fileReader.result).
}
Wy we are posting the data manually and not with help from XmlHttpRequest (or similar) is for easier overall posting to our web service from different parts of the web page (it's wrapped in a function). But that doesn't seem to be the problem.
The code in the Web Service looks like this
[WebMethod]
public string SaveFileValueFieldValue(string value)
{
System.Text.UnicodeEncoding encoder = new UnicodeEncoding();
byte[] bytes = encoder.GetBytes(value);
// Saves file from bytes here...
}
All works well, and the data seems to be normal, but when trying to open a file (an image as example) it cannot be opened. Very basic text files seems to turn out okay. But if I upload a "binary" file like an image and then open both the original and the uploaded version in a normal text editor as notepad to see what differs, it seems to be wrong with only a few "invisible" characters and something that displays as a new line a few bytes in from from the start.
So basicly, the file seems to encode just a few bytes wrong somewhere in the conversions.
I've also tried to create an int array in javascript from the data, and then again transformed to a byte[] in the web service, with the exact same problem. If I try to convert with anything else than unicode (like UTF-8), the data turns out completly different from the original, so I think om on the right track here, but with something slightly wrong.
The request itself is text, so binary data is lost if you send the wrong enc-type.
What you can do is encode the binary to base64 and decode it on the other side.
To change the enc-type to multi-part/mixed and set boundaries (just like an e-mail or something) you'd have to assemble the request yourself.

Categories

Resources