1

Is this the right way to read the content of a file picked by a filepicker? I need to read the image data in order to send it to a webservice in my Windows Metro Javascript App. I use a readFile function with a callback that returns an evt parameter and then use encodeURIComponent(evt.target.result):

document.getElementById("btnUpload").onclick = function () {
            var input = document.getElementById("file_input");
            readFile(input.files[0], function(file, evt)
            {
                WinJS.xhr({
                    type: "post",
                    url: "http://servlett.domain.com:8080/Servlet/addImage",
                    headers: { "Content-type": "application/x-www-form-urlencoded" },
                    data: "fk_floor_id=" + currentFloorId + "&map=" + encodeURIComponent(evt.target.result)
                }).then(
                    function (xhr) {
                        var success = xhr.response;
                        }, function (xhr) {
                        var error = xhr.response;
                    }
                );
            }); 

The parameter evt.target.result is retrieved through the following method:

function readFile(file, callback) {
var reader = new FileReader();
reader.onload = function (evt) {
    if (typeof callback == "function")
        callback(file, evt);
};
reader.readAsText(file);

}

where file_input is a input component inside the following form:

<form action="" method="post">
        <input type="file" id="file_input" />
        <button type="button" id="btnUpload">Upload</button>
    </form>

Thanks in advance.

Simon
  • 454
  • 7
  • 18

2 Answers2

1

A better solution is:

var picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.fileTypeFilter.replaceAll([".jpg", ".bmp", ".gif", ".png"]);
picker.pickSingleFileAsync().then(progressResults, displayError);

function progressResults(file) {
    file.openAsync(Windows.Storage.FileAccessMode.read).done(function (stream) {
     var inputStream = stream.getInputStreamAt(0);
     var reader = new Windows.Storage.Streams.DataReader(inputStream);
     var size = stream.size;
     if (size > 0) {
          reader.loadAsync(size).then(function () {
          var b = reader.readBuffer(size);
          var s = Windows.Security.Cryptography.CryptographicBuffer.encodeToBase64String(b);
                var xhrOptions = {
                    type: 'post',
                    url: "http://servlet.domain.com:8080/Servlet/addImage",
                            headers: { "Content-type": "application/x-www-form-urlencoded" },
                            data: "fk_floor_id=" + currentFloorId + "&map=" + s
                 }
                 WinJS.xhr(xhrOptions);
           });

 });
Simon
  • 454
  • 7
  • 18
0

There are few issues here:

  1. Reading the content of the file as text and sending to the webservice is not a good idea.
  2. using input type="file" will not give native look and feel in the app for picking an image.

Instead is good to pick and preview image on the lines of this msdn walk through. Along with this, the upload WinJS.xhr call will look little different.

There are other requirements that might be relevant in the scenario e.g. showing preview of the uploaded image to the web service. I have to take care of many other requirements for our winjs application when uploading image to the service. This post might be relevant for you for code listing and thinking about this holistically.

Sushil
  • 5,265
  • 2
  • 17
  • 15
  • Thank you for your answer it already helped me to understand some more methods. But why is it a bad idea to send the image as a text to the webservice (where the WS stores it as a blob in the DB)? The author of the (second) post uses MSApp.createFileFromStorageFile(file); to create a file and sends it over. But this is an object file inside the metro app, it is no content data that can be stored in the database, or am I wrong here? – Simon Nov 29 '13 at 08:41
  • when sending image as text, base64 encoding is required to not lose data. [this question](http://stackoverflow.com/questions/11402329/base64-encoded-image-size) gives data abt base64 disadvantages for storing n sending images. The data will be send as [blob payload](http://msdn.microsoft.com/en-us/library/windows/apps/ms536736.aspx) by xhr. The web server will have way to read the http request binary payload. e.g. in nodejs server, binary data is delivered as [Buffer](http://nodejs.org/api/buffer.html). – Sushil Nov 30 '13 at 03:32
  • Regards saving to database, pl check your database documentation. sql server supports [blob data type](http://msdn.microsoft.com/en-us/library/0t1k839z(v=vs.80).aspx) – Sushil Nov 30 '13 at 03:33