【问题标题】:Authenticated AJAX File Download经过身份验证的 AJAX 文件下载
【发布时间】:2013-03-17 19:49:21
【问题描述】:

我正在将 Intranet 与文档管理系统集成。 DMS 有一个 SOAP API。我们构建了一个客户端,它接收 REST 调用、发出 SOAP 调用并返回 JSON 或文档数据。

问题是 AJAX 文件下载的所有解决方案似乎都使​​用 iFrame(请参阅John Culniver's filedownload plugin)。

我不能使用它,因为我需要在标头中提供身份验证凭据。我能想到的唯一其他潜在解决方案是使用window.open(如果我可以通过浏览器弹出窗口阻止)。

有没有人有其他潜在的解决方案,或者如何使用 window.open 做到这一点?

谢谢

【问题讨论】:

  • @n1ckolas 他说的不是下载,不是上传吗?
  • 你用jQuery还是不用jQuery?
  • 确实如此。对不起,我的错。
  • 是的,肯定在寻找下载。 @ryan 是的,我正在使用 jQuery。
  • 也许我理解错了,但你看过$.ajax'sheadersbeforeSend属性吗?

标签: javascript ajax download


【解决方案1】:

我认为这个问题没有客户端解决方案。 window.open 不会让您设置请求标头。您需要执行一些操作,例如向服务器发送 cookie 或其他值,并添加服务器端代码以减少对请求标头的需求。

查看以下问题的答案:

【讨论】:

  • 感谢您。我突然想到我可能必须构建一个临时 URL 来提供文件并将用户指向它。我会看看他们是否有任何替代品并将它们发布在这里我找到任何。
  • 唉,我们通过下载 pdf 数据和creating a temporary URL.createObjectURL 接近了,但现代浏览器还没有完全到我们可以为二进制文件执行此操作的地步……至少这是我下班后发现的的挖掘。我将不得不临时提供文件并在 AJAX 响应中发送文档 URL。谢谢。
  • 我第二个@EricH。目前唯一的方法是创建一个具有唯一和随机 URI 的临时文件,通过 Ajax 请求将其发送回,然后在第二次链接单击或浏览器重定向中下载该文件。新路径不应该有任何身份验证
【解决方案2】:

我能够成功地做到这一点。我是我的示例,我使用的是基本身份验证,但是您可以将 Authorization 标头替换为不同的值(例如,您可以将其替换为 Bearer Yourtokenvalue

这里是代码sn-p

$(document).on("click", "#btn", function() {

  var username = "yourUserNameForBasicAuthentication";
  var password = "yourPasswordForBasicAuthentication"

  console.log("button clicked");
  var request = new XMLHttpRequest();
  request.open("GET", $("#txtUrl").val().trim(), true);

  //Set the authorization headers
  request.setRequestHeader("Authorization", "Basic " + window.btoa(username + ":" + password));

  //Set the Response type as blob which means raw data
  request.responseType = "blob";

  //We will initiate a default file name in case no file name is detected later on from headers of HTTP Request
  var fileName = "unnamed.pdf";
  request.onload = function(event) {
    if (request.status == 200) {
      console.log("success response received");
      var blob = request.response;

      //Getting contenttype from response headers
      var contentType = request.getResponseHeader("content-type");
      if (contentType == null) {
        contentType = "application/pdf";
      }

      //Check 'Content-Disposition' header to get filename of file (if possible)
      if (request.getResponseHeader("Content-Disposition")) {
        var contentDisposition = request.getResponseHeader("Content-Disposition");
        fileName = contentDisposition.substring(contentType.indexOf("=") + 1);
      }

      if (window.navigator.msSaveOrOpenBlob) {
        // Internet Explorer
        window.navigator.msSaveOrOpenBlob(new Blob([blob], {
          type: contentType
        }), fileName);
      } else {
        var el = document.createElement("a");
        document.body.appendChild(el);
        el.href = window.URL.createObjectURL(blob);
        el.download = fileName;
        el.click();
        el.remove();
        window.URL.revokeObjectURL(el.href);
      }


    } //end of Status code
    else {
      alert("System failed to authenticate");
    }

  } //End of event
  request.send();

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" value="https://yoursamplefile.txt" id="txtUrl" style="width:100%" /><br />
<input type='button' value='Download File' id='btn' />

【讨论】:

  • 像魅力一样工作(至少对于小文件)。我可以想象这会导致大文件出现问题(可能将所有内容保存在内存中,然后根据 if 创建一个数据 URI)。
  • @debuglevel 对于大文件我猜必须依赖其他因素。可能会在特定的有限时间秒内在服务器端生成具有加密文件名的文件,这可能会为您解决问题。 1. 使用通常的身份验证进行身份验证 2. 服务器使用 base64string 文件名从您的上传文件夹复制 3. 您提供下载该文件的链接 4. 在一段时间后删除该文件或 UI 中的某些活动表明文件下载已完成.
猜你喜欢
  • 2013-06-26
  • 1970-01-01
  • 2017-03-22
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
  • 2016-05-24
  • 2014-07-09
  • 1970-01-01
相关资源
最近更新 更多