首页 > 解决方案 > 如何修复通过 ajax 下载的文件名的编码?

问题描述

php get_dokument 中有一个 php-script,它会生成一个名为“Инструкция_по_работе_с_сайтом.pdf”(西里尔文)的文件并将其输出到浏览器。如果我直接在浏览器中访问 get_dokument,我会得到一个名为“Инструкция_по_работе_с_сайтом.pdf”的文件。如果我使用 ajax 帖子

var xhr = new XMLHttpRequest();
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=utf-8');
xhr.send($.param({ ajax:1,document_id:document_id,company_id:company_id,action:action}));

我在响应标头中看到的内容:

Cache-Control: must-revalidate
Connection: keep-alive
Content-Description: File Transfer
Content-Disposition: attachment; filename="Инструкция_по_работе_с_сайтом.pdf"
Content-Length: 143647
Content-Type: application/pdf; charset=utf-8
Date: Mon, 07 Sep 2020 08:11:02 GMT
Expires: 0
Pragma: public
Server: nginx/1.14.0 (Ubuntu)

但该文件以“Ð_нÑ_Ñ_Ñ_Ñ_кÑ_иÑ__по_Ñ_абоÑ_е_Ñ__Ñ_айÑ_ом.pdf”的名称打开。使用 base64 没有帮助

完整代码:PHP:

    $name = 'Инструкция_по_работе_с_сайтом';
    $filename_pdf = $name.'.pdf';
    $path = './uploads/dokuments/';
          header('Content-Description: File Transfer');
                header("Content-Type: application/pdf; charset=utf-8");
    header('Content-Disposition: attachment; filename="'.$filename_pdf.'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($path.$filename_pdf));
    readfile($path.$filename_pdf);
    unlink($path.$filename_pdf);

js:

var xhr = new XMLHttpRequest();
      xhr.open('POST', '<?=site_url('cabinet/dokuments/get_dokument');?>', true);
      xhr.responseType = 'arraybuffer';
      xhr.onload = function () {
          if (this.status === 200) {
              var filename = "";
              var disposition = xhr.getResponseHeader('Content-Disposition');
              if (disposition && disposition.indexOf('attachment') !== -1) {
                  var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
                  var matches = filenameRegex.exec(disposition);
                  if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
              }
              alert(filename);
              var type = xhr.getResponseHeader('Content-Type');

              var blob;
              if (typeof File === 'function') {
                  try {
                      blob = new File([this.response], filename, { type: type });
                  } catch (e) { /* Edge */ }
              }
              if (typeof blob === 'undefined') {
                  blob = new Blob([this.response], { type: type });
              }

              if (typeof window.navigator.msSaveBlob !== 'undefined') {
                  // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
                  window.navigator.msSaveBlob(blob, filename);
              } else {
                  var URL = window.URL || window.webkitURL;
                  var downloadUrl = URL.createObjectURL(blob);

                  if (filename) {
                      // use HTML5 a[download] attribute to specify filename
                      var a = document.createElement("a");
                      // safari doesn't support this yet
                      if (typeof a.download === 'undefined') {
                          window.location.href = downloadUrl;
                      } else {
                          a.href = downloadUrl;
                          a.download = filename;
                          document.body.appendChild(a);
                          a.click();
                      }
                  } else {
                      window.location.href = downloadUrl;
                  }

                  setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
              }
          }
      };
      xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=utf-8');
      xhr.send($.param({ ajax:1,document_id:document_id,company_id:company_id,action:action}));

标签: phpajax

解决方案


推荐阅读