如何使用Firefox扩展上传二进制内容?

时间:2012-12-16 10:48:10

标签: firefox firefox-addon

在我的Firefox扩展程序中,我下载了该文件,然后扩展程序应该上传它。我做了以下 -

// downloading file
var persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
                .createInstance(Components.interfaces.nsIWebBrowserPersist);
var file = Components.classes["@mozilla.org/file/directory_service;1"]
              .getService(Components.interfaces.nsIProperties)
              .get("TmpD", Components.interfaces.nsIFile);
file.append("temp.torrent");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);

var fURI = synoext.srv.io.newURI(url,null,null);
  const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
  const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
  persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_FROM_CACHE;
persist.progressListener = {
  onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress) {
    },
  onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus) {
    if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP) {
      // file has been downloaded, upload it 
      Components.utils.import("resource://gre/modules/NetUtil.jsm");
      NetUtil.asyncFetch(file, function(inputStream, status) {
        if (!Components.isSuccessCode(status)) {
          return;
        }

        var filedata = NetUtil.readInputStreamToString(inputStream, inputStream.available());
        var boundary = "-----------------------ZzzZzzZzz";

        var postdata = "--"+boundary+"\r\n";
        postdata += "Content-Disposition: form-data; name=\"api\""+"\r\n";
        postdata += "\r\n";
        postdata += "SYNO.DownloadStation.Task"+"\r\n";

        postdata += "--"+boundary+"\r\n";
        postdata += "Content-Disposition: form-data; name=\"version\""+"\r\n";
        postdata += "\r\n";
        postdata += "1"+"\r\n";

        postdata += "--"+boundary+"\r\n";
        postdata += "Content-Disposition: form-data; name=\"method\""+"\r\n";
        postdata += "\r\n";
        postdata += "create"+"\r\n";

        postdata += "--"+boundary+"\r\n";
        postdata += "Content-Disposition: form-data; name=\"file\"; filename=\""+file.leafName+"\""+"\r\n";
        postdata += "Content-Type: application/x-bittorrent"+"\r\n";
        postdata += "\r\n";
        postdata += filedata;
        postdata += "--"+boundary;
        postdata += "\r\n";

        var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                            .createInstance(Components.interfaces.nsIXMLHttpRequest);
        req.open('POST', "http://192.168.1.5:5000/webapi/DownloadStation/task.cgi", true); // asynch
        req.onload = function() {
          // file uploaded
        };

        req.setRequestHeader('Content-Type', 'multipart/form-data; boundary='+boundary);
        // req.setRequestHeader('Content-Length', postdata.length);
        req.send(postdata);
      });

但文件上传不正确。我的测试用例中的原始文件是31Kb,但上传的文件是46Kb。如果我检查filedata.length,那么它是正确的 - 31Kb。

1 个答案:

答案 0 :(得分:4)

不要自己创建POST主体,而是使用FormData对象。

var formData = Components.classes["@mozilla.org/files/formdata;1"].createInstance(Components.interfaces.nsIDOMFormData);
formData.append(key, value);

formData.append("file", File(file));