如何下载然后上传文件?

时间:2011-07-28 18:25:06

标签: javascript firefox-addon xmlhttprequest

尝试使用以下代码,但无法正常运行:

  // download the file first
  var req = new XMLHttpRequest();
  req.open('GET', url, false);
  req.overrideMimeType('text/plain; charset=x-user-defined');
  req.send(null);
  if (req.status != 200) return '';

  // upload the file
  req.open("POST", "http://mysite.com/upload", false);
  req.setRequestHeader("Content-Length", req.responseText.length);
  req.sendAsBinary(req.responseText); // What should I pass here?

  if (req.status != 200) return '';
  return req.responseText;

sendAsBinary是firefox function

更新。此外,我还尝试将其作为表单的一部分上传:

var response = req.responseText;
var formData = new FormData();
formData.append("file", response);
req.open("POST", "http://mysite.com/upload", false);
req.send(formData);

但服务器仍未收到完整数据。

2 个答案:

答案 0 :(得分:3)

最后我使用了临时文件的方法:

  var downloadCompleted = false;

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

  var fURI = Services.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) {
         downloadCompleted = true; // file has been downloaded        
      }
    }
  }
  persist.saveURI(fURI, null, null, null, "", file);  

  var thread = Components.classes["@mozilla.org/thread-manager;1"]
                        .getService(Components.interfaces.nsIThreadManager)
                        .currentThread;
  while (!downloadCompleted) // emulate synchronous request, not recommended approach
    thread.processNextEvent(true); 

  // upload the file
  var stream = Components.classes["@mozilla.org/network/file-input-stream;1"]
                       .createInstance(Components.interfaces.nsIFileInputStream);
  stream.init(file, 0x04 | 0x08, 0644, 0x04); // file is an nsIFile instance   

  // try to determine the MIME type of the file
  var mimeType = "text/plain";
  try {
    var mimeService = Components.classes["@mozilla.org/mime;1"]
            .getService(Components.interfaces.nsIMIMEService);
    mimeType = mimeService.getTypeFromFile(file); // file is an nsIFile instance
  }
  catch(e) { /* just use text/plain */ }

  var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                      .createInstance(Components.interfaces.nsIXMLHttpRequest);
  req.open('POST', "http://mysite.com/upload", false); 
  req.setRequestHeader('Content-Type', mimeType);
  req.send(stream);

  // delete the file
  file.remove(false);

答案 1 :(得分:2)

在重用responseText对象之前,您需要将req存储在中间变量中。

// download the file first
var req = new XMLHttpRequest();
req.open('GET', url, false);
req.overrideMimeType('text/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) return '';
var response = req.responseText;

// upload the file
req.open("POST", "http://mysite.com/upload", false);
req.setRequestHeader("Content-Length", response.length);
req.sendAsBinary(response);
if (req.status != 200) return '';
return req.responseText;

<强>更新

根据MDN页面Using XMLHttpRequest,上面的代码看起来不起作用。以下是获取二进制响应的正确方法。最后,您将拥有一组无符号整数,您可以将它们发送回服务器并转换为二进制。我想。

//req.responseType is only defined for FF6+
req.responseType = "arraybuffer";
req.send(null);

//req.response is for FF6+, req.mozResponseArrayBuffer is for FF < 6
var buffer = req.mozResponseArrayBuffer || req.response;
if (buffer) {
  var byteArray = new Uint8Array(buffer);
}

更新2

要将byteArray提交给服务器,我会尝试以下未测试的内容,几乎可以保证不会使用代码。

req.open("POST", "http://mysite.com/upload", false);
req.setRequestHeader("Content-Length", byteArray.length);
//if this doesn't work, try byteArray.buffer
//if byteArray.buffer works, try skipping 'var byteArray = new Uint8Array(buffer);' altogether and just sending the buffer directly
req.send(byteArray); 

更新3

Using XMLHttpRequest from JavaScript modules / XPCOM components可能与您的问题有关吗?

相关问题