base64_encode in javascript

Asked

Viewed 3,176 times

2

I have an image in the database saved in blob format, I have to use the base64_encode in php before returning the ajax request and this slows down the process on the server side. Can do or has any native function on javascript or jQuery to do the same base64_encode php on client side in javascript ?

current scenario: javascript

fun.ajaxFoto = custom.ajaxAsync(p,'getFoto','../view/rh/vFuncionarioDetalhes.php');
fun.ajaxFoto.done(function(json){
    $("#fun_foto").empty();
    var img = $('<img>').attr('src',"data:image/jpg;base64," + json.fun_foto);
});

goes to the vFunctionaryDetails.php file

function getFoto(){
    global $colFuncionario; 

    $obj = (object) $_REQUEST['obj'];

    $json = $colFuncionario->getFoto($obj);

    // QUERIA MUDAR ESSA LINHA ABAIXO E ENTREGAR DIRETO O $json->fun_foto
    $json->fun_foto = base64_encode( $json->fun_foto );
    echo json_encode( $json );
}

Controller

public function getFoto($obj){
            global $c;
            $objResult = new stdClass();

            $c->conCordilheira();
            $mQuery = "select * from tab_cordilheira_ferias_gozo where fun_id =".$obj->fun_id;
            $query = "SELECT fd.foto as fun_foto FROM fundocumento fd where fd.cd_empresa=2011 and fd.cd_funcionario=".$obj->fun_id;

            $result = mssql_query($query);                
            $obj02 = mssql_fetch_object($result);
            //$result = odbc_exec($conn, $query);

            $c->conectarNovamente(@$_SESSION["usuario"],@$_SESSION["senha"]);
            $mResult = mysql_query($mQuery);
            $objM    = mysql_fetch_object($mResult);
            //$obj02 = odbc_fetch_object($result);

            $objResult->fun_dt_ferias = $objM->fun_mes_gozo;                
            $objResult->fun_foto =  $obj02->fun_foto;

            return $objResult;
        }

I will leave String in blob format so it is possible to test

$json->fun_foto="0xFFD8FFE1348345786966000049492A000800000011000E01020020000000DA0000000F01020005000000FA0000001001020009000000000100001A010500010000000A0100001B0105000100000012010000280103000100000002008A8732010200140000001A01000013020300010000000200838169870400010000004A01000001A40300010000000000898902A40300010000000000837F03A40300010000000000857F06A40300010000000000877E08A403000100000000007D7409A40300010000000000887F0AA403000100000000008179A5C407001C0000002E010000501500002020202020202020202020202020202020202020202020202020202020202000534F4E5900004453432D57333230000048000000010000004800000001000000323031333A30333A30342031363A30353A3234005072696E74494D00303330300000020002000100000001010100000016009A82050001000000580200009D820500010000006002000022880300010000000200FEFB27880300010000004006FFFB00900700040000003032323103900200140000006802000004900200140000007C02000001910700040000000102030002910500010000009002000004920A0001000000980200000592050001000000A002000007920300010000000500FFFF08920300010000000000FFFF09920300010000001000FFFE0A92050001000000A80200007C920700A0120000B002000000A00700040000003031303001A00300010000000100FFFF02A0040001000000B00A000003A0040001000000400E000000A307000100000003FEFEFE01A3070001000000015F605F000000000A000000E80300002D0000000A000000323031333A30333A30342031363A30353A323400323031333A30333A30342031363A30353A32340003000000010..."
  • Not to send via JSON. JSON is a text format, if you want to send binary data in the same first you need to turn it into text (is what the base64_encode is doing). If you do not want to do this conversion on the server, you would need to send the data in the original format, for example in a second request where the client would expect a image/jpeg.

  • I notice that the only data that seems to be being used by the client side is the photo itself. Would it be an option not to use Ajax? Simply create an element <img src="função no servidor que retorna o blob com mimetype image/jpeg" style="display: none" onload="função que esvazia #fun_foto e exibe a imagem escondida"> and add it to the correct place?

  • 2

    Honestly, I think this is a "XY problem": what was asked is whether to convert between binary/Base64 in Javascript (which gives, as Guilherme Nascimento’s answer and the duplicate question show), but the real problem seems to be how to send the blob to the client without having to do any conversion on the server side. If I’m wrong, I’ll remove that comment soon.

  • *did not fit the whole string I cut the final p/ manage to post

  • @mgibsonbr what I want to do is this, I want to deliver what is on my server to the client and from there transform this string in image

  • It would be interesting to know where the $_REQUEST['obj']

  • @Sneepsninja But you didn’t say that the image is in your bank as a blob? blob != string. The blob doesn’t need to be transformed into image, the blob is image! So I’m of the opinion that the most performative way to do what you want is what I described in my above comment. Unless it is clear that you are sending other data next to the image (which by the JS presented does not seem to be the case).

  • @Guilhermenascimento the $_REQUEST['obj'] is to make the query in the bank that part this ok, I did not find necessary in the question because it has only a code of the employee that will be consulted in the database

  • 1

    Why BLOB instead of saving to files?

  • But $_REQUEST['obj'] should bring data from the front end and not from the bank, does not agree?

  • 1

    @Guilhermenascimento From what I understand, the front-end says which employee he wants the photo of ($_REQUEST['obj']) and the PHP code will fetch this photo in the database ($colFuncionario->getFoto($obj);). I don’t know exactly how this happens because I have no experience with PHP, but that’s what I understood from the above code.

  • 1

    @mgibsonbr comes together in ajax other data concerning the employee’s vacation updated the question p/ show this detail

  • {the front-end says which employee of whom he wants the photo ($_REQUEST['obj']) and the PHP code will fetch this photo in the bank} that’s right

  • @mgibsonbr but it’s like I said then $_REQUEST['obj'] comes really from the front-end, even if previously the data is from the database, still an ajax request is made and sends the data again to then query the image, so I thought it was relevant to know how the data is sent to $_REQUEST['obj']. I still don’t understand why you store photos in the bank instead of folders, it is quite possible that this is the performance problem you are facing.

  • I made a new edition in the answer, I hope it helps to understand the problems that the BLOB can bring and that is probably your real problem :)

Show 10 more comments

2 answers

3


Base64 and javascript

The equivalent functions in javascript sane:

  • window.btoa to encode
  • window.atob to decode

Source: https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64

var data = window.prompt("Digite a sua string:");

if (data) {
    var b64 = window.btoa(data);
    alert("Codificado: " + b64);
    alert("Decodificado: " + window.atob(b64));
} else {
    alert("Nada foi digitado");
}

The use in your case I think would be something like:

var img = $('<img />').attr('src', "data:image/jpg;base64," + window.btoa(SUA STRING));

Server performance

What seems to be causing performance problems is not the base64, but yes the way you stored the images, maybe the best way is to stop using BLOB and move on to store the images in folders, that besides probably having better performance will be much easier to work since you will not need to create a dynamic page to display the data.

There are problems when using BLOB and so I do the reply from @utluiz my:

  • Data volume: for a low volume of data may be no problem. On the other hand, for large data mass storage the database is practically unviable. Ask Facebook or Google if they would use a bank. Facebook, for example, uses a custom file system to make access even faster and decrease the overhead per file required by traditional file systems.
  • Clustering: One advantage of the database is that if your system runs on multiple servers, everyone will have uniform access to the files. However, use a drive on the network to store the files.
  • Availability: your system will have many accesses? This may overload a traditional database. On the other hand, your HTTP server can use low-level file system access routines to send the data stream to the client.
  • Scalability: If demand for volume or availability increases, is it possible to add more capacity to the system? It’s much easier to split files between different servers than to distribute records from one table to more servers.
  • Flexibility: make backups, move files from one server to another, do some processing on the stored files, all this is easier if the files are in a directory. If you deploy in client environment, the files on disk nay make it impossible for you to receive copies of the database for testing. Try asking your client to send terabytes of data for you to analyze if there is a problem in the database.
  • Overhead read and write: the computational cost to write and read database data is greater than to read and write directly to a file.

And this is what should be causing your performance problem on the server.

  • These methods are to convert strings to Base64 and vice versa, no? In case AP has binary data (a blob image). Or do these methods also work for blobs? (anyway, there’s still the question of how to send the blob inside a JSON)

  • @mgibsonbr the base64_encode as much as the window.btoa, or better the Base64 itself is used for carrying "binary" data, such as images, whether front-end or back-end, so much so that using Base64 for ascii strings can fail, as in the Mozilla documentation itself, when ascii data is used it is necessary to use encodeuri, then yes, it will depend on how it will want to implement, but the use of Base64 is this same basically.

  • Ok, I’m a little confused (it seems I’ve interpreted the question in a different way than you’ve interpreted), but I’ll take a closer look at these functions before making any evaluation.

2

Javascript does have functions that convert from and to Base64, see the answer of Guilherme Nascimento. However, this does not change the fact that you will have to convert your image from BLOB to string before including it in JSON (since JSON is a text format, and does not accept binary data unless expressed in text form).

Base 64 is one of the most compact ways to represent binary data in text, so any alternative would certainly have worse overall performance. You could try encoding your BLOB in hexadecimal, as proposed in the issue to the question, but even if the server processing is faster the JSON download time (and the bandwidth consumed) will be higher, besides the fact of the conversion is clear client-side take even more time. You relieve the load on the server, but at the cost of worse performance and more traffic (which your server still has to spend).

My suggestion is do not upload the photo to JSON, but simply make a second request to get it. No Ajax. Simply do, on the return of the first Ajax request (which returns a JSON), something like:

fun.ajaxFoto.done(function(json){
    $("#fun_foto").empty();
    var img = $('<img>').attr('src',"pegaFoto.php?funid=" + json.fun_id);
});

And in his pegaFoto.php you already return the Blob directly in binary format, with the mimetype imagem/jpeg (see in the documentation of your bridge with the DBMS how to do this).

  • I’ll see if it works with this technique and return with the results

  • @Sneepsninja Ok. If you want more help, please tell me which DBMS you are using, and I can complement the answer with PHP code as well (I just found an example for Firebird/Interbase so far)

  • 1

    SGBD is sql server, maybe the performance problem is this, I do a query in sqlSever and another in Mysql, the picture of the goat is on a system I’m migrating to Mysql, so I haven’t finished migrating that system so I have to deliver the data this way half-half....

Browser other questions tagged

You are not signed in. Login or sign up in order to post.