3

Been trying to get the following code to work in firefox add-on:

var oMyForm = new FormData();

oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456); // number 123456 is immediately converted to string "123456"

// HTML file input user's choice...
oMyForm.append("userfile", fileInputElement.files[0]);

// JavaScript file-like object...
var oFileBody = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...
var oBlob = new Blob([oFileBody], { type: "text/xml"});

oMyForm.append("webmasterfile", oBlob);

var oReq = new XMLHttpRequest();
oReq.open("POST", "http://foo.com/submitform.php");
oReq.send(oMyForm);

from https://developer.mozilla.org/en-US/docs/Web/Guide/Using_FormData_Objects?redirectlocale=en-US&redirectslug=Web%2FAPI%2FFormData%2FUsing_FormData_Objects

So I know I have to use XPCOM, but I can't find the equivalent. I found this so far:

var oMyForm = Cc["@mozilla.org/files/formdata;1"].createInstance(Ci.nsIDOMFormData);

oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456); // number 123456 is immediately converted to string "123456"

// JavaScript file-like object...
var oFileBody = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...
var oBlob = Cc["@mozilla.org/files/file;1"].createInstance(Ci.nsIDOMFile, [oFileBody], { type: "text/xml"});

oMyForm.append("webmasterfile", oBlob);

var oReq = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
oReq.open("POST", "http://localhost:3000");
oReq.send(oMyForm);

Essentially the problem is var oBlob = Cc["@mozilla.org/files/file;1"].createInstance(Ci.nsIDOMFile, [oFileBody], { type: "text/xml"}); because "@mozilla.org/files/file;1" or Ci.nsIDOMFile is incorrect. Note that nsIDOMFile is inherits from nsIDOMBlob.

Anyone know what to do?

Thanks a bunch.

nmaier
  • 32,336
  • 5
  • 63
  • 78
s12chung
  • 1,718
  • 1
  • 14
  • 29

1 Answers1

6

Let's cheat a little to answer this:

  • JS Code Modules actually have Blob and File, while SDK modules do not :(
  • Cu.import() will return the full global of a code module, incl. Blob.
  • Knowing that, we can just get a valid Blob by importing a known module, such as Services.jsm

Complete, tested example, based on your code:

const {Cc, Ci, Cu} = require("chrome");
// This is the cheat ;)
const {Blob, File} = Cu.import("resource://gre/modules/Services.jsm", {});

var oMyForm = Cc["@mozilla.org/files/formdata;1"].createInstance(Ci.nsIDOMFormData);

oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456); // number 123456 is immediately converted to string "123456"

// JavaScript file-like object...
var oFileBody = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...
var oBlob = Blob([oFileBody], { type: "text/xml"});

oMyForm.append("webmasterfile", oBlob, "myfile.html");

var oReq = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
oReq.open("POST", "http://example.org/");
oReq.send(oMyForm);
nmaier
  • 32,336
  • 5
  • 63
  • 78
  • Heh, after years of using and abusing the platform I know quite a bit by now. The cheat I discovered by accident quite some time ago. The rest is trial-and-error... Oh, and I look into the [source](http://mxr.mozilla.org/) a lot! – nmaier Nov 05 '13 at 02:43
  • This is spectacular!! – Noitidart Oct 30 '14 at 21:29
  • It looks like something changed and you cant get `Blob` or `File` like this anymore: http://stackoverflow.com/questions/27893399/how-do-i-use-the-dom-file-api-from-privileged-code – Noitidart Jan 12 '15 at 00:49