如何下载然后上传文件?

发布于 2024-11-26 15:06:28 字数 944 浏览 0 评论 0原文

尝试使用以下代码,但无法正常工作:

  // 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 is 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);

但服务器仍然没有收到完整的数据。

Tried to use the following code, but it doesn't work properly:

  // 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 is firefox function.

Upd. Also I've tried to upload that as part of the form:

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

But still not full data is received by the server.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烙印 2024-12-03 15:06:28

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

  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);

Finally I've used the approach with temp file:

  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);
如歌彻婉言 2024-12-03 15:06:28

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

// 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

可以从 JavaScript 模块/ XPCOM 使用 XMLHttpRequest组件与您的问题有什么关系?

You need to store the responseText in an intermediate variable before reusing the req object.

// 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;

Update

Per the MDN page Using XMLHttpRequest, it looks like the above code won't work. Following is the proper way to get the binary response. In the end, you will have an array of unsigned integers which you could send back to the server and convert to binary. I think.

//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);
}

Update 2

To submit the byteArray to a server, I would try something like the following untested, almost guaranteed not to work code.

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); 

Update 3

Could Using XMLHttpRequest from JavaScript modules / XPCOM components have anything to do with your issue?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文