Как скачать, а затем загрузить файл? - PullRequest
3 голосов
/ 28 июля 2011

Пытался использовать следующий код, но он не работает должным образом:

  // 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 функция .

Upd. Также я попытался загрузить это как часть формы:

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

Но сервер все еще не получает полные данные.

Ответы [ 2 ]

3 голосов
/ 31 июля 2011

Наконец я использовал подход с временным файлом:

  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);
2 голосов
/ 28 июля 2011

Вам необходимо сохранить 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 Используя 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

Может Использование XMLHttpRequest из модулей JavaScript / компонентов XPCOM есть что-то сделатьс вашей проблемой?

...