Hi,
How can I replace the functionality of an HTML file widget form like
this

<form enctype="multipart/form-data" method="POST"
        action="http://server/filehandler";>
Local file: <input name="clientfile" type="file"/>
<input name="submit" type="submit" value="Upload"/>
</form>

with pure JavaScript?

This form works fine with the server-side script, where the uploaded
file is saved to a temporary file that can be worked on.

But the reason why I want to do this in JavaScript is to allow the user
to select multiple files with a nsIFilePicker and then send each file
to the same server url in a loop.

I've tried using XMLHttpRequest as suggested in a previous thread in
this group (subject: "nsIUploadChannel help", Dec 7 2004) like this:

const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
           .createInstance(nsIFilePicker);
fp.init(window, "File Picker", nsIFilePicker.modeOpenMultiple);
fp.appendFilters(nsIFilePicker.filterAll);
var rv = fp.show();
if (rv == nsIFilePicker.returnOK) {
  var files = fp.files;
  var file;
  var jsFile;
  while(files.hasMoreElements()) {
    file = files.getNext()
             .QueryInterface(Components.interfaces.nsILocalFile);
    jsFile = new File(file.path);  // JSLib file
    jsFile.open();
    var sData = "clientfile=" + encodeURIComponent( jsFile.read() );
    var req = new XMLHttpRequest;
    req.open("POST", "http://server/filehandler";, false);
    req.setRequestHeader("Content-Type",
                           "application/x-www-form-urlencoded");
    req.setRequestHeader("Content-Length", sData.length);
    req.send(sData);
    if (req.status / 100 == 2)
      alert(req.responseText);
  }
}

But only the initial characters of a non-pure-ascii file (like a Word
document) get through.

Then I've tried using nsIUploadChannel, so the previous while loop is
like:
...
  while(files.hasMoreElements()) {
    file = files.getNext()
             .QueryInterface(Components.interfaces.nsILocalFile);

    var uploadURI =
      ioService.newURI("http://server/filehandler";, null, null);
    var ioChannel = ioService.newChannelFromURI(uploadURI);
    var uploadChannel =
      ioChannel.QueryInterface(Components.interfaces.nsIUploadChannel);

    fileStream =
      Components.classes["@mozilla.org/network/file-input-stream;1"]
        .createInstance(Components.interfaces.nsIFileInputStream);
    fileStream.init(file, 0x01, 00004, null);

    uploadChannel.setUploadStream(fileStream, "", -1);

    var httpChannel =
      ioChannel.QueryInterface(Components.interfaces.nsIHttpChannel);
    httpChannel.requestMethod = "POST";

    httpChannel.open();
  }
...

With no luck.  I don't see how to provide a key (parameter name, like
"clientfile") with this method.

Can anyone provide an example of how to implement a multi-file upload
functionality for a XUL client?

Any advice would be appreciated. 
/Bjorn

_______________________________________________
Mozilla-netlib mailing list
Mozilla-netlib@mozilla.org
http://mail.mozilla.org/listinfo/mozilla-netlib

Reply via email to