Here are the steps my application is doing:
- User uploads an image (.PNG) file in the browser.
- Browser sends the raw image data to my server.
- The server then saves the file in my file system.
The problem is that my file system complains that the file is not a PNG file when I try to open it.
I'm trying to localize where the problem occurs without success. When I look at the file data using VIM it looks the same to me, with the same number of lines and the file contents both start with:
<89>PNG^M
^Z
^@^@^@^MIHDR^@^@^BD^@^@^@Î^H^B^@^@^@P6<8a><9a>^@^@^@^CsBIT^H^H^HÛáOà^ ^@^@_zTXtRaw profile type APP1^@^@^H<99>ãJOÍK-ÊLV((ÊOËÌIåR^@^Cc^S. ^SK^SK£D^C^C^C^K^C^H04006^D<92>F@
...
However, the file sizes are different, with the file I'm writing from my server being larger. So obviously they are different in some way.
I tried doing diff file1 file2
in the command line and it just gives me binary files differ
without showing me the difference... ?? Strange.
So I'm currently confused about how the files differ, and where in my code this difference gets introduced...
I feel I'm missing some crucial knowledge about how some things work here under the hood, and I would very much appreciate if someone smarter than me could help me out here.
Code
Client:
<input id="icon-button-file" type="file" onChange={handleChange} />
<label htmlFor="icon-button-file">
<Button/>
</label>
function handleChange(event: any) {
if (!event.target.files[0]) return
const file = event.target.files[0]
const reader = new FileReader()
reader.onload = function (e) {
const instance = axios.create({
baseURL: 'http://localhost:3000/',
timeout: 5000,
headers: { 'Content-Type': 'application/json' }
})
instance.post(
'image',
JSON.stringify({
imageData: e.target.result.toString()
})
).then(result => {
console.log(result)
})
}
reader.readAsBinaryString(file)
}
Server:
app.post(`http://localhost:3000/image`, (req, res) => {
fs.writeFile('img.png', req.body.imageData, (err) => {
console.log(err)
})
})
EDIT:
I made it work by sending the image content to the server as a dataUrl instead, using reader.readAsDataUrl()
. This encodes the image data as a Base64 string, which seems like a common practice. However, I'm still curious why sending the raw data doesn't work.