14

I'm trying to find any examples of uploading a file with a Dart script.

I understand the part about reading it on the client side after being selected in a file input field, but how can I POST it to the server and save it as a file?

Darshan Rivka Whittle
  • 32,989
  • 7
  • 91
  • 109
samer.ali
  • 396
  • 2
  • 3
  • 11
  • 1
    We pretty much need a parser for multipart encoding. I can write one this weekend, maybe even today when I get home. – Kai Sellgren Nov 09 '12 at 10:17

1 Answers1

13

Until a multipart encoding parser is available, you can use File API on client to read and upload file content as dataUrl. This API has quite good support in browsers ( see http://caniuse.com/filereader ).

On client side :

import 'dart:html';

main() {
  InputElement uploadInput = query('#upload');
  uploadInput.onChange.listen((e) {
    // read file content as dataURL
    final files = uploadInput.files;
    if (files.length == 1) {
      final file = files[0];
      final reader = new FileReader();
      reader.onLoad.listen((e) {
        sendDatas(reader.result);
      });
      reader.readAsDataUrl(file);
    }
  });
}

/// send data to server
sendDatas(dynamic data) {
  final req = new HttpRequest();
  req.onReadyStateChange.listen((Event e) {
    if (req.readyState == HttpRequest.DONE &&
        (req.status == 200 || req.status == 0)) {
      window.alert("upload complete");
    }
  });
  req.open("POST", "http://127.0.0.1:8080/upload");
  req.send(data);
}

And on server side :

import 'dart:io';

main() {
  final server = new HttpServer();
  server.listen('127.0.0.1', 8080);
  server.addRequestHandler((request) => request.path == '/upload' 
      && request.method.toLowerCase() == 'post'
      , (HttpRequest request, HttpResponse response) {
    _readBody(request, (body) {

      // handle your dataURL
      // example with image : data:image/jpeg;base64,/9j/4S2YRXhpZgAATU0AK... 

      // return result
      response.statusCode = HttpStatus.CREATED;
      response.contentLength = 0;
      response.outputStream.close();
    });
  });
}

/// Read body of [request] and call [handleBody] when complete.
_readBody(HttpRequest request, void handleBody(String body)) {
  String bodyString = ""; // request body byte data
  final completer = new Completer();
  final sis = new StringInputStream(request.inputStream, Encoding.UTF_8);
  sis.onData = (){
    bodyString = bodyString.concat(sis.read());
  };
  sis.onClosed = () {
    completer.complete("");
  };
  sis.onError = (Exception e) {
    print('exeption occured : ${e.toString()}');
  };
  // process the request and send a response
  completer.future.then((_){
    handleBody(bodyString);
  });
}

References :

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
Alexandre Ardhuin
  • 71,959
  • 15
  • 151
  • 132
  • Thanks Alexandre, however do you know how to decode the base64 string and save it to file in Dart? been looking for php alternative base64_decode – samer.ali Nov 09 '12 at 17:38
  • To write a file in dart, you can have a look at http://www.dartlang.org/articles/io/ . Base64 was only for the example. But unfortunatly, base64ToBytes is not available in dart for the moment ( http://dartbug.com/2458 ) To work around you could perhaps use `reader.readAsText(file)` or `reader.readAsBinaryString(file)` instead of `reader.readAsDataURL(file)`. – Alexandre Ardhuin Nov 09 '12 at 18:03
  • Thanks for your Help Alexandre, i developed my own decoder on the server side for the datauri and base64, and it's working great, i will try to share it sometime. – samer.ali Nov 09 '12 at 21:34
  • Is this still the way to go? Copied and pasted the code, but looks the classes cannot be imported – fritz-playmaker Feb 11 '19 at 17:22