var oReq = new XMLHttpRequest();
var reader = new FileReader();
reader.onload = function(e) {
var rawData = reader.result;
oReq.open("POST", '/upload', true);
oReq.send(rawData);
console.log(rawData);
}
reader.readAsBinaryString(postObj);
// postObj is an image who's src is set to a data uri, taken via a webcam.
console.log(rawData) yields ==>
"PNG
IHDRÈÜÇ IDATx^d½idizw"##rϬ}ëîªÞfÃ!%2
ø£üølpµ0ù Q&É©¡,Ú2l²!æSeÃ$Y-ÉÎLïKuí{îáëºófe³§¦*3#Nó¾Ïr?÷³¼úOþÓùÉ tóne¸Øm.»ÙhÐtÃÅQ7<w''³nοg³Y·Èkóãn<Xì§G]·²Ø
ç]·8wÇ\å¨;á5vÁ°Ì»E¾?æ÷ywtÒuó¯ù{>Ïám]ÇëF£Qwt|\ßó5ä³NæÜÇ°^{r¿ùÜÁ|¡;>:êón0âß¼gûã6rm_ëgçõü4[vG¼gaa!?_à5#~³0\èxcß}Â}ú|ÜÓóóÅ!Ï=?â{®ã½ó^í½v'ü×úþÞ/×ñÏ}P®}Â÷ݸ;9fX¨?[àUÇ|?à^|þáb=çòɸ[æ·¬#7q]>giÜqÓ~#oq´èMdY4í3-.ùÈzÿü̺Íy
7Ľֺؿ\Ü6¯õ:Ü ß·5r-|ºv½½ôú¬w¶ìõáþ<{/íuí{ÞÎÚy¯Gì%kÎ}NfÓÚÞã5ݶÏÞÔr×
ø«Õッk¯õï</ëïçz¬ïso§ÙsƳü5öß»{ÛÝádÌñö ïgÍÿù¿üWÝƹÝøüX7øK?ùó ê¶/!Ë«ÝÂxÔ"
G.²Éxbæ]ñg#úýgé£Þ;¿ThƳ/ùòû(D¿Ã>2Þ-ð³7¯18"P<=ç>GSr±;r\à;³°<6ÎòZNAázndûûtù¼1ÇVGÁ¼^vܼ\3ÚÆu¸9×g]ÉñA V°0óîÍ£TÃY½ïdaM">ÆhÎF9ú¿](3¯¢xeÜõt
¢DÞN¾E¾oÈEy×q®?ÂÀ»z=Bó|,¯JáæzíýÞ¯ÿöï&äM!rϼWóQÛ^ÏÛÖ5÷ܤûåϸÛüûÃkôF©]ß¿óÜ1F¤üNëÍsM¯Qü²úYX:f¯DSßÌõ4D1eTÛûüvÿþlrpÐM'SÇuòµÈïù?øî½>è~â'~¢ü$
How can I interpret this in Python? On the server, this data shows up as:
'...\x7f\xc2\xb4r\xc2\x87\x1c\xc2\xaa\n-\xc2\x9c\xc2\xa6QF\xc2\xac\xc2\xb0tS\xc3\xa4\xc2\xb0;\xc3\x8cisL#\xc3\x98\xc2\x94E\xc3\x94\xc2\xb8Bz\xc3\xb0\xc3\xa9\xc2\xaa#8\xc2\x90\xc3\xbb\xc3\xa5>\xc3\xbaO\xc2\xa8\xc3\x81H\xc3\x91\xc2\xaf:i\xc2\x8a\xc2\x926\xc2\x8b\xc2\x81\xc3\xbc\xc3\xa1Y\xc3\x93\xc2\x9b\xc2\xbat\xc2\x8f\xc3\x9e~\xc2\xa3PH4\x02_\x04\xc2\xbf\xc2\x92\xc2\xb7\xc3\xad\xc2\x8f\xc3\x9e\xc3\xbf\xc2\xb8<\xc2\x91V\xc3\xa0\xc3\x8b\x1f\xc3\x88\xc3\x9f\xc2\xa2>)\x1d\xc3\x94eY=\xc3\x8ct\xc2\xa9+L^7\xc2\xa2I\xc3\x84\xc2\xba\x03\xc3\xb5!1f\xc3\x97\xc3\x81\xc3\xbfD\xc3\x87\xc3\xb7\x06\xc2\xaa\xc3\xafcz\xc3\xad(\xc3\xb5\xc2\xab\xc3\x96\xc3\xb5<\xc3\x8e\xc2\xab\x08\xc3\x81\xc2\x88\x0b\xc3\x8a;\xc3\x8e!v\xc3\x84\xc2\xb1?\xc2\x8bVn\x19t\xc3\x80\xc2\x8bT`:\x1c\xc3\x8b\xc2\x99\xc3\xb2\xc3\x9c\xc3\xbf\x0fCsXi\xc3\xa6z\xc3\xb3l\x00\x00\x00\x00IEND\xc2\xaeB`\xc2\x82'
Writing this to file as a PNG yields an invalid PNG. Any guidance on saving the image would be helpful.
You will need to convert your image's binary representation into Base64 before uploading - this makes it safe to work with when transferring data over HTTP.
When you receive the Base64 encoded image server-side, you can convert it back to binary, and write this to a file.
Client side code:
To convert to Base64, you need to use
fileReader.readAsDataURL( fileObject )
this automatically represents your data in a safe to upload via HTTP format.
Server side code:
import base64
coded_string = '''Q5YACgA...'''
binary = base64.b64decode(coded_string)
# now write binary to file...
open('/path/to/new_file.png', 'wb').write(rawData)
On the browser:
// Client Side:
var xhr = new XMLHttpRequest();
xhr.open('POST', uploadUrl);
xhr.send(base64EncodedItem);
On the server (I am using Flask/Python 2.x)
# Server Side:
import re
import uuid
# Obtain the base64 string
image_string = request.data
image_string = re.search(r'base64,(.*)', image_string).group(1)
# Generate a file name.
# We can assume PNG format in my specific implementation, but you could search
# the image_string variable to detect filetype.
output = open(str(uuid.uuid4()) + '.png', 'wb')
output.write(image_string.decode('base64'))
output.close()
This worked for me. Hope it helps others.
Related
I have integrated a file upload into my web app. The file should not be uploaded but the MD5 hash of the file should be calculated on the client side and then only this hash should be sent to the server.
Javascript part:
if (input.files && input.files[0]) {
let reader = new FileReader();
reader.onload = (e) => {
let data = e.target.result;
var hashed = CryptoJS.MD5(data);
console.log('hashed: ' + hashed);
}
reader.readAsDataURL(input.files[0]);
}
However, the code above gives me different hash as terminal does (md5sum ).Terminal gives me the same hash as various online converters.
It is the same with SHA1 and SHA256 algorithms I tried.
Example:
This image from Wikipedia gives the following hashes.
Terminal: e5d23cb99614778b2acb163b8ee90810
CryptoJS: 468641711626fcfe6d956ddb21ccd4c7
readAsDataURL() is going to return a base64 string (with a data URI preamble) so that's what your hashing however an MD5 terminal tool is just going to read the raw bytes & hash them as-is.
To fix use:
reader.readAsArrayBuffer(input.files[0]);
to fetch the raw bytes and:
var hashed = CryptoJS.MD5(CryptoJS.lib.WordArray.create(data));
to pass them to CryptoJs in a format it can process.
I want to upload a file as JSON from the client to a Python webserver (Tornado) and save it on the server. This is my simplified setup:
Client HTML:
<input type="file" id="myFile" onchange="fileChange" />
Client JS:
function fileChange(event) {
const file = event.target.files[0];
const fileReader = new FileReader();
fileReader.onload = (e) => uploadFile(e.target.result, file.name);
fileReader.readAsText(file);
}
function uploadFile(fileContent, fileName) {
const data = {fileContent, fileName};
axios.post('http://localhost:8080/api/uploadFile', JSON.srtingify(data));
}
Python Webserver:
class UploadFileHandler(tornado.web.RequestHandler):
def post(self):
requestBody = tornado.escape.json_decode(self.request.body)
file = open(requestBody["fileName"], "w+")
file.write(requestBody["fileContent"].encode("UTF-8"))
file.close()
All uploaded files are empty (blank pages in a PDF, file type of JPG is 'not supported', Word file cannot be opened) and are nearly twice as big as the original file. How can I fix this?
Is there a way to improve this setup?
You are trying to upload binary files (word, jpg), serialised as JSON, and store them on the server.
To handle binary data in JSON, encode the binary data as base64 first, then call JSON.stringify.
Like this (untested):
function uploadFile(fileContent, fileName) {
// Encode the binary data to as base64.
const data = {
fileContent: btoa(fileContent),
fileName: fileName
};
axios.post('http://localhost:8080/api/uploadFile', JSON.stringify(data));
}
On the server side, you need to deserialise from JSON, decode the base64 and the open a file in binary mode to ensure that what you are writing to disk is the uploaded binary data. Opening the file in text mode requires that the data be encoded before writing to disk, and this encoding step will corrupt binary data.
Something like this ought to work:
class UploadFileHandler(tornado.web.RequestHandler):
def post(self):
requestBody = tornado.escape.json_decode(self.request.body)
# Decode binary content from base64
binary_data = base64.b64decode(requestBody[fileContent])
# Open file in binary mode
with open(requestBody["fileName"], "wb") as f:
f.write(binary_data)
I'm using the management API to get all my installed apps and extensions. I want to send this information to server.
Every app/extension has an icon array, that has size and url.
The url is something like chrome://extension-icon/gmgpodcgeocidkeclglljo88jp9kclhhmmdacfo/32/0. I want to send it to my server in base64.
What I'm trying to do is something like:
var reader = new FileReader();
reader.onloadend = function() {
result = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
result = "";
}
Where file is a File object of the icon url. But I cannot find how to create an File object with this url format.
I've tried:
var fileUrlArray = ["chrome://extension-icon/gmgpodcgeocidkeclglljo88jp9kclhhmmdacfo/32/0"];
var file = new File(fileUrlArray, 'icon.png');
And as a result I got an absolutely wrong base64 string.
Any ideas about how to do it?
Thanks.
I have a webapp that is saving images locally until they are ready to be sent to the server. When I save the images locally, I base64 encode them. Now I want to do a multipart file upload with these images.
So I need to convert the image back into binary form. I've tried using the FileReader to convert it back like this,
var fr = new FileReader();
fr.onloadend = function(binaryImage){
debugger;
binaryImage;
};
var base64Str = item.base64Image.substr(item.base64Image.indexOf("base64") + 7);
//var base64Str = item.base64Image;
fr.readAsBinaryString(base64Str);
but the onloadend event is never fired and there are no errors. Once I get the image I wont have trouble uploading it. Any ideas?
Thanks!
Not to familiar with FileReader, but I believe readAsBinaryString is expecting a Blob or File object. Passing it a string causes errors on my end. Try this:
var fr = new FileReader();
fr.onloadend = function(binaryImage){
debugger;
binaryImage;
};
var blob = new Blob([item.base64Image.
substr(item.base64Image.indexOf("base64") + 7)]);
fr.readAsBinaryString(blob);
I don't think this will give you want though. Check out this article for ways to encode/decode Base64: How can you encode to Base64 using Javascript?
Looks like you can use btoa() and atob() for web kit browsers.
lets say i have a URL given. I would like to:
1) download it and convert to base64
2) upload it to some key/value storage (as text)
3) download it from key/value storage (with text/plain mimetype), reencode it from base64, display it.
Best Regards
If someone is still searching for downloading images and encoding them in base64 string, I recently find this kind of outdated method but really reliable. The advantage is that it's pure Javascript so there is no need to install any external library. I previously tried using fetch and axios but for some reason the encoded string was not in a correct format.
NB: If you are encoding this image to send it to an API, some of them require to delete the leading data type including the , at the start of the encoded string.
function toDataURL (url, callback) {
const xhRequest = new XMLHttpRequest()
xhRequest.onload = function () {
const reader = new FileReader()
reader.onloadend = function () {
callback(reader.result)
}
reader.readAsDataURL(xhRequest.response)
}
xhRequest.open('GET', url)
xhRequest.responseType = 'blob'
xhRequest.send()
}
const URL = "https://upload.wikimedia.org/wikipedia/commons/f/f7/Stack_Overflow_logo.png"
const logCallback = (base64image) => {
// Base64 encoded string with leading data type like
// data:image/png;base64,RAW_ENCODED_DATA______
console.log(base64image)
}
toDataURL(URL, logCallback)