Search code examples
javascriptnode.jsfile-uploadsocket.io

Simple and easy way to upload file to node server with socketio/javascript?


I've been trying modules and libraries for the last couple of hours. From socketio-fileupload to other of that sort. None worked for me. I just want something basic and simple if possible. I'm unable to transfer the file to the server. How can I do this with the least hassle possible?

html

 <input required type='file' id="imageUpload" accept=".png, .jpg, .jpeg" />
    
<button class="saveImage">Upload Image</button>

client

function updateAvatar(){
$('.saveImage').on('click',function(){
        
var file = $('#imageUpload').val();
var filename = file.name;
var filesize = file.size;
var enc = file.encoding;
        
console.log(file);
        
socket.emit('update-avatar', {
data : file,
size : filesize,
name : filename,
enc : enc
}
);
});
}

server

socket.on('update-avatar',function(data){
    
console.log(data);
var filename = path.basename(data.name);
var filepath = path.join('./uploads', filename);  
    
});

Solution

  • Here simple way to upload image to Nodejs using socketio. Works for me using FileReader(). No need for library just send everything through base64. You do need fs module(npm install fs). I'm posting the whole thing here.

    With this code snippet you will be able to

    • Upload image/file from HTML with javascript fileReader
    • Encode/Decode base64 file
    • Transfer file in real time using socketio/nodejs

    Server

    //load fs module
    const fs = require('fs');
        
    /*
        
    Upload file to folder
    Send image back to client to display in real time
        
    */
        
    socket.on('update-avatar',function(json){
            
    //variables
    var image = json.data.file;
    var data = image.replace(/^data:image\/\w+;base64,/, '');
    var fileName =  'user'+userid+Date.now() + "image.png";
            
    //upload to folder
    fs.writeFile("../user/upload/" + fileName, data, {encoding: 'base64'}, function(err){
            
            
    if(err){
            
    console.log(err);
    
    }else{
    
    //success
    //return image back to js-client
    io.to(socketid).emit('avatar-updated',{valid:'true',message:'success',buffer: data.toString('base64') 
    });
    }
    });
    });
    

    client

    /*
    
    DISPLAY AVATAR
    
    */
    document.getElementById("imageUpload").onchange = function () { displayAvatar() };
    
    function displayAvatar() {
    const file = document.getElementById("imageUpload").files[0];
    const reader = new FileReader();
    reader.onloadend = function () {
    document.getElementById('clock').style.backgroundImage = "url(" + reader.result + ")";
    $('.saveImage').show('slow');
    $('.cancelImage').show('slow');
    }
    if (file) {
    reader.readAsDataURL(file);
    } else {
        
    }
    }
    /*
    
    
    UPLOAD AVATAR
    
    
    */
    function updateAvatar(){
    
    $(".saveImage").on('click', function() {
    // validate type of file
    if(['image/jpeg', 'image/jpg', 'image/png', 'image/gif'].indexOf($("#imageUpload").get(0).files[0].type) == -1) {
    alert('Error : Only JPEG, PNG & GIF allowed');
    return;
    }
    
    var reader = new FileReader();
    reader.onload = function(){
    var $data = {'file': reader.result };
    
    //send 
    socket.emit('update-avatar',{data:$data});
    };
    reader.readAsDataURL($("#imageUpload").get(0).files[0]);    
    });
    
    
    }
    /*FILE UPLOAD AVATAR.HTML*/
    .avatar-upload {
    position: relative;
    max-width: 205px;
    margin: 50px auto;
    }
    .avatar-upload .avatar-edit {
    position: absolute;
    right: 12px;
    z-index: 1;
    top: 10px;
    }
    .avatar-upload .avatar-edit input {
    display: none;
    }
    .avatar-upload .avatar-edit input + label {
    display: inline-block;
    width: 34px;
    height: 34px;
    margin-bottom: 0;
    border-radius: 100%;
    background: #FFFFFF;
    border: 1px solid transparent;
    box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.12);
    cursor: pointer;
    font-weight: normal;
    transition: all 0.2s ease-in-out;
    }
    .avatar-upload .avatar-edit input + label:hover {
    background: #f1f1f1;
    border-color: #d6d6d6;
    }
    .avatar-upload .avatar-edit input + label:after {
    font-family: 'FontAwesome';
    color: #757575;
    position: absolute;
    top: 10px;
    left: 0;
    right: 0;
    text-align: center;
    margin: auto;
    }
    .avatar-upload .avatar-preview {
    width: 192px;
    height: 192px;
    position: relative;
    border-radius: 100%;
    text-align: center !important;
    border: 6px solid grey;
    box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);
    }
    .avatar-upload .avatar-preview > div {
    background-image: url('');
    width: 100%;
    height: 100%;
    border-radius: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center;
    }
    .saveImage{
    display:none;
    }
    .cancelImage{
    display:none;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="list no-border">
    <div class="item">
    <div class="avatarContainer">
    <div class="avatar-upload">
    <div class="avatar-edit">
    <input required type='file' id="imageUpload" accept=".png, .jpg, .jpeg" />
    <label class="ion icon ion-camera text-grey" for="imageUpload"><img style="width:35px;" src="https://www.islesburghdramagroup.com/wp-content/uploads/2015/07/Image-Edition-Tools-Screenshot-icon.png" /></label>
    </div>
    <div class="avatar-preview">
    <div id="clock" style="background-image: url(img/icon.png);">
    </div>
    </div>
    
    </div>
    </div>
    </div>
    
    <div style="text-align:center;" class="item align-center">
    <button class="icon ion ion-checkmark-round saveImage green button">Save</button>
    <button id="cancelImage" class="icon ion ion-close-round cancelImage red button">Cancel</button>
    
    </div>
    </div>