【问题标题】:PDF File download from AJAX Post success callback从 AJAX 下载 PDF 文件发布成功回调
【发布时间】:2017-01-22 17:00:48
【问题描述】:

当我尝试链接到已设置为呈现为 PDF 文档的数据生成文件时,这可以在新窗口中打开 PDF 文档,但仅适用于少量数据:

window.open(myUrl + params, "_blank", "menubar=no,status=no");

我需要它来处理这样的事情,这样我才能使我的 PDF 与更大的数据集兼容。我尝试在 ajax 请求的数据部分传递参数,但它不适用于 PDF 文档。它适用于 Word 和 Excel 文档。当我尝试与 PDF 相同的操作时,它会将下载返回到损坏的 PDF 对象。

$.ajax({
   type:"POST",
   async:true,
   url: myUrl,
   data: params,
   success: function(result,status,jqhxr) {                 
         var blob=new Blob([result]);
       var link=document.createElement('a');
       link.setAttribute('target','_blank');
       link.href=window.URL.createObjectURL(blob);
       link.download="PreviewProposalAsPdf.pdf";
       link.click();                    
   }
});

我需要做什么才能正确呈现 PDF?理想情况下,我想在新窗口中直接导航到 PDF 页面,但我会满足于可点击的文件下载。如果可能,请直接发布完整的解决方案。我花了很多时间在这上面,现在我的时间不多了。

我寻找其他问题的解决方案,但没有一个解决方案有效。在某些情况下,我已经在尝试发布作为解决方案。请帮忙。

谢谢

【问题讨论】:

    标签: javascript jquery ajax pdf post


    【解决方案1】:

    这是正确答案,不使用 SaveAs 功能:

    var req = new XMLHttpRequest();
    req.open("POST", myUrl, true);
    
    req.responseType = "blob";
    
    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    req.send(data);
    
    req.onreadystatechange = function() {//Call a function when the state changes.
        if(req.readyState == 4 && req.status == 200) {
            console.log(req.responseText);
        }
    }
    
    req.onload = function (event) {
       var blob = req.response;
       console.log(blob.size);
       var link=document.createElement('a');
       link.href=window.URL.createObjectURL(blob);
       link.download="Dossier_" + new Date() + ".pdf";
       link.click();
    };
    

    最终解决了我的问题。谢谢你,无尽的。

    【讨论】:

      【解决方案2】:

      使用 jQuery ajax 得到的结果是纯文本,并且可能导致将二进制文件下载为文本而不是 arrayBuffer 或 blob 时“超出范围”。 jQuery 不以任何方式支持 responseType(据我所知)

      因此,您需要依靠 xhr 或 fetch 将其作为 blob 来获取正确的内容。否则你会得到损坏的数据

      这里是使用新的fetch api 和FileSaver 的示例

      function saveAs(blob, filename){
          if(navigator.msSaveOrOpenBlob)
              return navigator.msSaveOrOpenBlob(blob, filename)
      
          var link = document.createElement('a')
          link.href = window.URL.createObjectURL(blob)
          link.download = filename
          link.click()
      }
      
      fetch(myUrl, {
          method: 'post', 
          body: JSON.stringify(params)
          headers: {
              'Content-Type': 'application/json;charset=UTF-8'
          }
      })
      .then(res => res.blob())
      .then(blob => saveAs(blob, 'PreviewProposalAsPdf.pdf'))
      
      
      // EXAMPLE USING XHR
      var req = new XMLHttpRequest
      req.open('GET', myUrl, true)
      req.responseType = 'blob'
      req.onload = function() {
          saveAs(res.response, 'Dossier_' + new Date() + '.pdf')
      }
      req.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
      req.send(JSON.stringify(params))
      

      但是ofc,如果你使用xhr + responseType = blob,会有更广泛的支持

      您能做的最好的事情就是发送 content-disposition 标头并制作附件 - 但是您不能使用 ajax...需要提交表单(可能来自 iframe)

      【讨论】:

      • 您没有将参数发布为正文,而是在 url 中使用了它们。查看我更新的示例
      猜你喜欢
      • 2023-03-30
      • 2017-03-14
      • 2011-11-26
      • 2016-11-26
      • 1970-01-01
      • 2016-05-11
      • 1970-01-01
      • 2016-12-28
      • 1970-01-01
      相关资源
      最近更新 更多