简体   繁体   中英

Saving a base64 PNG Image on a nodeJS server

I've viewed plenty of similar questions on stack overflow and have attempted the noted solutions but none has worked for me. I honestly can't figure out what i'm doing wrong.

Heres a snippet of the code...

Node.JS ServerFile

function uploadAvatar(request){
return new Promise(function(resolve){
    if(request.sessionObject.username){
        base64 = (request.postObject.data).replace(/^data:image\/png;base64,/, "");
        fpath = __dirname + "/gg/avatars/" + request.sessionObject.username + ".png";
        fs.writeFile(fpath, base64, 'base64', function(err) {
            alertObject = alertObj("success","Success","You have succesfully uploaded an avatar.", false, false, 2000);
            resolve(alertObject);
        });
    }else{
        alertObject = alertObj("danger","Error","You must be logged in in order to upload an avatar.", false, false, 2000);
        resolve(alertObject);
    }
});
}

app.post("*", function(request, response, next){
postObject = {};
for(x in request.body){
    postObject[x] = sanitizer.sanitize(request.body[x]);
}
request.postObject = postObject;

function r(html, obj){
    response.render(html, obj);
}

switch(request.originalUrl){
    case "/uploadAvatar":
    uploadAvatar(request).then(function(alertObject){ r('HTML_Alert', {alertObject}) });
    break;
}

HTML_Modal (View file)

<div class="modal fade" id="uploadAvatar" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
  <div class="modal-header background-dark">
    <img src="/upload.png" width="30px" height="30px" />
    <h5 class="modal-title">Upload Avatar</h5>
    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <form id="upload-avatar">
      <label class="lead w-100 text-center">Please select an Image</label>
      <p id="image-response" class="text-center"></p>
      <div id="image-container" class="mx-auto p-2 border-dark background-darkest img-thumbnail">
        <img src="/load.png" style="left: 50%; position: absolute; margin-left: -25px; top: 50%; margin-top: -50px;"/>
      </div><br/>
      <input type="file" id="avatar-image-upload" class="form-control" onchange="imageResizer(event)" accept="image/*"/>
    </form>
  </div>
  <div class="modal-footer">
    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
    <button type="button" class="btn btn-dark" onClick="uploadAvatar();">Upload</button>
  </div>
</div>
</div>
</div>

Javascript File

function xhttpz(action, dataSTR, cb){
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
    if(this.readyState == 4 && this.status == 200){
        if(cb){
            cb(this.responseText);
        }
    }
}
xhttp.open("POST", action, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(dataSTR);    
}

function imageResizer(event){
img = document.getElementById('image-avatar');
if(img){
    img.remove();
}
document.getElementById('image-container').innerHTML = "";
if(event.target.files[0].size < 500000){
    var files = event.target.files;
    var file = files[0];
    imageAvatar = document.createElement('img');
    imageAvatar.id = "image-avatar";
    if (file) {
    var reader = new FileReader();
    reader.onload = function(e) {
        imageAvatar.src = e.target.result;
        document.getElementById('image-container').appendChild(imageAvatar);
    };
    reader.readAsDataURL(file);
    }
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        var filesToUploads = document.getElementById('avatar-image-upload').files;
        var file = filesToUploads[0];
        if (file) {
            var reader = new FileReader();
            reader.onload = function(e) {
                var img = document.createElement("img");
                img.src = e.target.result;
                var canvas = document.createElement("canvas");
                var ctx = canvas.getContext("2d");
                ctx.drawImage(img, 0, 0);
                var MAX_WIDTH = 300;
                var MAX_HEIGHT = 225;
                var width = img.width;
                var height = img.height;
                if (width > height) {
                    if (width > MAX_WIDTH) {
                        height *= MAX_WIDTH / width;
                        width = MAX_WIDTH;
                    }
                } else {
                    if (height > MAX_HEIGHT) {
                        width *= MAX_HEIGHT / height;
                        height = MAX_HEIGHT;
                    }
                }
                canvas.width = width;
                canvas.height = height;
                var ctx = canvas.getContext("2d");
                ctx.drawImage(img, 0, 0, width, height);
                dataurl = canvas.toDataURL();
                document.getElementById('image-avatar').src = dataurl;
                document.getElementById('image-response').innerHTML = "Please wait as we upload your image.";
                document.getElementById('image-response').classList.add('text-success');
                document.getElementById('image-response').classList.remove('text-danger');
                xhttpz("/uploadAvatar", "data="+document.getElementById('image-avatar').src, function(responseHTML){
                    console.log(responseHTML);
                });
            }
            reader.readAsDataURL(file);
        }
    }else{
        document.getElementById('image-response').innerHTML = "Your browser does not support our API. Please consider using Chrome.";
        document.getElementById('image-response').classList.add('text-danger');
        document.getElementById('image-response').classList.remove('text-success');
    }
}else{
    document.getElementById('image-response').innerHTML = "Please ensure your image is under 500KB.";
    document.getElementById('image-response').classList.add('text-danger');
    document.getElementById('image-response').classList.remove('text-success');
}
}

Note: The request.postObject.data variable is a base64 string of a png image. (If that's correct)

Most of the code is superfluous, however I kept it all in tack just to help find the issue.

So the issue that I keep running into is that the file saves perfectly into the specified file path, however the file itself is either unreadable or corrupted. Essentially all i'm trying to do is save a base64 string as a png image on the server.

Note i'm using Node.js

I know this might be close to a duplicate question, but i've attempted all the solutions that we're posted on similar topics and none has worked.

Please ensure that your base64 variable is decoding well using a tool like https://www.base64-image.de/ and that your fpath variable is correct.

Then,

require("fs").writeFile(fpath, base64, 'base64', function(err) {
  console.log(err);
});

Should work

Edit :

Just try

xhttpz("/uploadAvatar", document.getElementById('image-avatar').src, function(responseHTML){
    console.log(responseHTML);
});

and

base64 = (request.data).replace(/^data:image\/png;base64,/, "");

Replace the xhttpz function

xhttpz("/uploadAvatar", "data="+document.getElementById('image-avatar').src, 
function(responseHTML){
    console.log(responseHTML);
});

with

xhr.open("POST","/uploadAvatar",true);
xhr.setRequestHeader('Content-Type','x-www-form-urlencoded');
xhr.send("Filedata="+imageAvatar.src);

Then change the base64 variable to reference the newly stated 'Filedata.'

fpath = (__dirname + "/html/avatars/" + sessionObject.username + ".png");
var bodyStr = '';
request.on("data",function(chunk){
    bodyStr += chunk.toString();
});
request.on("end",function(){
    base64 = (bodyStr).replace("Filedata=data:image/png;base64,","");
    fs.writeFile(fpath, base64, 'base64', function(err){
        alertObject = alertObj("success","Success","You have successfully uploaded an avatar.", false, true, 2000);
        resolve(alertObject);
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM