【问题标题】:Setting a filename to a blob before uploading it在上传之前将文件名设置为 blob
【发布时间】:2020-01-14 07:40:14
【问题描述】:

我需要使用blob将图像文件上传到服务器,但是上传后的文件名总是设置为“blob”,或者下载时源代码文件的名称+.jpg。我的代码在 Chrome 上运行,但我需要它在 IE10 上运行,不幸的是我不知道如何。

我要做的是:

function uploadBlob() {
    var fileName = //insert method to get the original filename of the file uploaded here...

    var blob = dataURItoBlob(dataURL); //this method gets an image, compresses it and returns it as blob

    var blob2 = new Blob([blob], { type: "image/jpeg" });
                      blob2.lastModifiedDate = new Date();
                      blob2.name = fileName;

    return blob2;
}

使用 File Constructor 会更容易,但 IE 和 Edge 不支持它。该函数需要返回一个文件或一个blob,并且使用我当前的代码上传到服务器就好了,只是文件名不正确。我该如何解决这个问题?

【问题讨论】:

    标签: javascript blob internet-explorer-10


    【解决方案1】:

    您的文件上传是请求的一部分。您可以将文件名作为同一请求的单独参数传递。如果这不是您的选择,那么您可以在上传 blob 之前创建一个请求,方法是发送文件名并设置一个会话变量,因此将在下一个请求时知道,当上传 blob 时。但是,如果可能,请将文件名参数单独传递给请求,而不仅仅是作为 blob 的名称,因为它似乎是您的情况的错误。

    【讨论】:

    • 感谢您的回答。将文件名单独传递给服务器是一个非常可行的替代方案,并且有效,但是公司真正想要的是一种万无一失的方法,它可以接收所有内容并返回所有必要的内容......我会继续寻找一种方法,但你的回答非常有帮助.再次感谢。
    • @DootyBooty 我完全理解你。如果这个想法,您可以对 IE10 有与其他浏览器不同的行为以最小化域。如果你发现更好的东西,那么请在这里分享,很高兴知道它可以用更优雅的方式解决。
    【解决方案2】:

    当您上传文件时,您可以创建一个包含文件名和文件内容(blob)的FormData 对象,然后发布到服务器,并将它们存储在具有不同列的同一个数据表中。

    我们在下载文件的时候可以得到文件名和文件内容,然后从服务器端获取数据后,可以参考下面的代码下载文件:

    //IE11 and Edge browser support
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
       return navigator.msSaveOrOpenBlob(file.content, file.name);
        }
        else{
            var link = document.createElement('a');
            link.href = window.URL.createObjectURL(file.content);
            link.download = file.name;
            document.body.appendChild(link);
            link.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));
            link.remove();
            window.URL.revokeObjectURL(link.href);
        }
    

    如果使用IE和Edge浏览器,我们可以使用msSaveOrOpenBlob或msSaveBlob方法下载文件,对于其他浏览器,我们可以创建一个html元素并使用download属性下载文件。

    【讨论】:

      【解决方案3】:

      你没有展示你是如何将这个 Blob 发送到你的服务器的,但是没有太多的方法,所以让我们来探索一下:

      最常见的做法是将 Blob 作为 multipart 表单数据请求的一部分发送给您。

      为此,您可以使用 HTML <form> 发布内部方法或 AJAX,但是,虽然现在可以通过黑客在这样的 HTML <form> 中设置任意数据,但这些黑客需要您设置一个文件名,因此我们可以很容易地假设您不在这种情况下。
      所以这给我们留下了AJAX。

      要使用 AJAX 发送这样的多部分请求,您可能正在使用 FormData 对象及其 append() 方法。
      此方法在与 Blob(或文件)一起使用时接受三个参数:

      • 用于访问服务器数据的字段键(这对应于<input> 中<input> 的name 属性<form>)。
      • Blob(或文件),将其二进制数据设置为字段值。
      • 可选文件名。(对于文件,如果未设置此参数,则使用其name 属性。)

      所以在代码中

      const your_blob = new Blob(['some data'], { type: 'text/plain'} );
      
      const formData = new FormData();
      formData.append('file_key', your_blob, 'myfile.txt');
      
      /* Then you can send this FormData through AJAX
       *   const xhr = new XMLHttpRequest();
       *   xhr.open('POST', your_url);
       *   xhr.send(formData);
       * or
       *   fetch( {
       *     method: "POST",
       *     url: your_url,
       *     body: formData
       *   } );
       */
      // for this demo we'll just print the request's content:
      new Response(formData)
        .text()
        .then(console.log);

      将此 Blob 发送到您的服务器的另一个选项是使用 AJAX 将二进制数据作为原始 POST 请求直接发送。
      这可以通过将 Blob 直接传递给 XMLHttpRequest.send() 方法或作为 fetch 请求的 body 属性来完成。

      在这种情况下,文件名将被丢弃,只有 Content-Type 将由浏览器设置。
      因此,要在这种请求中传递文件名,我们需要使用自定义 HTTP 标头。

      const xhr = new XMLHttpRequest();
      xhr.open('POST', your_url);
      xhr.setRequestHeader('X-filename', your_filename);
      xhr.send(your_blob);
      
      // or
      
      fetch( your_url, {
        method: "POST",
        headers: { "X-filename": your_filename },
        body: your_blob
      } );
      

      然后您必须从服务器端检索此标头的内容。

      【讨论】:

      • 感谢您的回答。是的,正如您所猜到的,数据是通过 AJAX 通过服务器上传的。我们将要发送的所有数据放入content[ ] 数组中,并将该数组发送给后端处理。虽然我们的 AJAX 在“只是”调用 XMLHttpRequest 的方式上并不传统,但您的回答仍然很有帮助。如果我能在此基础上解决问题,我会注意的。
      猜你喜欢
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2020-03-09
      • 1970-01-01
      相关资源
      最近更新 更多