【问题标题】:XMLHttpRequest sending .PDF to PHP and saving on server, results in some data corruptionXMLHttpRequest 将 .PDF 发送到 PHP 并保存在服务器上,导致某些数据损坏
【发布时间】:2023-08-04 02:30:02
【问题描述】:

我有一个 blob 形式的 pdf 文件,我正在尝试将其发送到 php 以将其本地保存到我的网络服务器。目前,如果我使用 saveAs() 在本地保存 pdf,则 pdf 是可读且未损坏的。但是,一旦将数据作为表单数据发送到我的 php 脚本,它会保存在一个较大的文件大小中,这会导致数据丢失,最终无法在 adobe reader 中打开。

我已经区分了两个相邻的 pdf,您可以看到某些字符没有被复制。

Diffed PDFs, Left is working PDF, right is corrupted

我正在使用 FileReader 读取 blob,并将结果附加到 formdata。然后我使用 XMLHttpRequest 将数据发送到我的 pdf,它会在其中写入文件。

我假设这是一个编码错误,但我对文件的编码方式知之甚少,无法自行进行有根据的调查。

 function transferData(){              
            var data = new FormData();
            var reader = new FileReader();
            reader.readAsBinaryString(blobHolder);
            reader.addEventListener('loadend',
                    function(){
                    data.append("data" , reader.result);
                    var xhr2 = new XMLHttpRequest();
                    xhr2.open( 'post', 'php/savefile.php', true );
                    xhr2.send(data);
            });
      }
<?php

if(!empty($_POST['data'])){
$data = $_POST['data'];
$fname = "serverGeneratedPDF.pdf";

$file = fopen("../upload/" .$fname, 'w+');
fwrite($file, $data);
fclose($file);
}

?>

【问题讨论】:

    标签: javascript php xmlhttprequest filereader


    【解决方案1】:

    想用我如何让它工作来更新这个问题。

    我最终将整个 blob 对象作为 formData 发送,而不是使用 FileReader。然后,在我的 PHP 文件中,我使用了 file_get_contents() 函数,最终挽救了这一天。它能够从发送过来的 blob 中提取硬“数据”!!!

    更新代码:

    JS:

     function transferData(){              
                        var data = new FormData();
                        data.append('sentBlob', blobHolder);
                        var xhr2 = new XMLHttpRequest();
                        xhr2.open( 'post', 'php/savefile.php', true );
                        xhr2.send(data);
                  }
    

    PHP:

    <?php
    
    $data = file_get_contents($_FILES['sentBlob']['tmp_name']);
    $fname = "serverGeneratedPDF.pdf";
    
    $file = fopen("../upload/" .$fname, 'wb');//creates new file
    fwrite($file, $data);
    fclose($file);
    
    ?>
    

    我的“啊哈”时刻正在弄清楚两件事:

    1. 我的 blob 发送到 $_FILES var 而不是 $_POST
    2. 一旦 php 处理了 blob,使用 '$_FILES[]['tmp_name']' 最终是从 blob 中获取原始二进制数据的方法(我花了好几天才达到这一点)

    希望这对某人有所帮助!

    【讨论】: