【问题标题】:AJAX POST to download and upload PDF fileAJAX POST 下载和上传 PDF 文件
【发布时间】:2014-08-04 06:03:20
【问题描述】:

我想编写一个 chrome 扩展程序,从接受 POST 请求的网站下载 PDF 文件,并将 PDF 文件上传到我的 localhost 服务器。这是我的尝试:

  $.ajax({
        url: 'http://example.com/download.action',
        data: data,
        type: 'POST',
        cache: false,
        crossDomain: true,
        success: function(response) {
            $.ajax({
                url: 'http://localhost/getpdf.php',
                data: response,
                type: 'POST',
                cache: false,
                contentType: 'application/octet-stream',
                processData: false,
                crossDomain: true
            });
        }
    });

从控制台我观察到下载ajax请求的响应,它是一个以“%PDF-1.7.%...”开头的二进制内容,看起来是合理的。然后在 localhost 服务器端,我使用一些简单的 PHP 代码来保存 PDF 文件:

<?php
$raw_data = file_get_contents('php://input');
$f = fopen('test.pdf', 'w');
fwrite($f, $raw_data);
fclose($f);
?>

文件已保存。但是保存的PDF文件无法用Adobe Reader打开(文件损坏),而且文件大小比原来的大2倍左右。

我检查了保存的 PDF 文件的二进制文件和 vim -b 的原始文件,这里是前 10 行:

原来的:

0000000: 2550 4446 2d31 2e37 0a25 e4e3 cfd2 0a36  %PDF-1.7.%.....6
0000010: 2030 206f 626a 0a3c 3c2f 5479 7065 2f58   0 obj.<</Type/X
0000020: 4f62 6a65 6374 0a2f 5375 6274 7970 652f  Object./Subtype/
0000030: 466f 726d 0a2f 4242 6f78 5b30 2030 2035  Form./BBox[0 0 5
0000040: 3935 2e32 3736 2038 3431 2e38 395d 0a2f  95.276 841.89]./
0000050: 5265 736f 7572 6365 733c 3c2f 584f 626a  Resources<</XObj
0000060: 6563 743c 3c2f 496d 3020 3720 3020 522f  ect<</Im0 7 0 R/
0000070: 496d 3120 3820 3020 522f 496d 3220 3920  Im1 8 0 R/Im2 9 
0000080: 3020 523e 3e2f 436f 6c6f 7253 7061 6365  0 R>>/ColorSpace
0000090: 3c3c 2f43 5330 2031 3020 3020 522f 4353  <</CS0 10 0 R/CS

保存的:

0000000: 2550 4446 2d31 2e37 0a25 efbf bdef bfbd  %PDF-1.7.%......
0000010: efbf bdef bfbd 0a36 2030 206f 626a 0a3c  .......6 0 obj.<
0000020: 3c2f 5479 7065 2f58 4f62 6a65 6374 0a2f  </Type/XObject./
0000030: 5375 6274 7970 652f 466f 726d 0a2f 4242  Subtype/Form./BB
0000040: 6f78 5b30 2030 2035 3935 2e32 3736 2038  ox[0 0 595.276 8
0000050: 3431 2e38 395d 0a2f 5265 736f 7572 6365  41.89]./Resource
0000060: 733c 3c2f 584f 626a 6563 743c 3c2f 496d  s<</XObject<</Im
0000070: 3020 3720 3020 522f 496d 3120 3820 3020  0 7 0 R/Im1 8 0 
0000080: 522f 496d 3220 3920 3020 523e 3e2f 436f  R/Im2 9 0 R>>/Co
0000090: 6c6f 7253 7061 6365 3c3c 2f43 5330 2031  lorSpace<</CS0 1

好像有些词变了(可能是字符集问题?)

对此有何提示?

【问题讨论】:

  • 可能是字符集问题 - 是的,大于 128 的字节被 UTF-8 中的 Unicode Character 'REPLACEMENT CHARACTER'、efbfbd 替换。但是,PDF 是二进制数据,因此根本不应该发生与字符集相关的替换。尝试将b(二进制)添加到fopen 模式。
  • @mkl 谢谢,我尝试添加b,但问题仍然存在。可能是javascript方面的问题?
  • 可能是javascript方面的问题 - 可能是的。您的十六进制转储看起来像是中间的某个步骤将 PDF 视为 ASCII 文本(因此替换每个字节 >127)。是哪一步,我不知道。

标签: php ajax pdf


【解决方案1】:

您可能希望使用这种方式来读取 pdf 文本,然后将其写入新的 pdf 文件

how to get text from pdf file and save it into DB

【讨论】:

    【解决方案2】:

    终于找到了符合我要求的解决方案。

    正如@mkl 所提到的,在原始PDF 二进制数据上对UTF-8 进行了一些替换,但我们不知道这种替换发生在哪一步。于是我开始搜索发送/接收二进制数据而不是字符串,我发现this,它引入了一个名为“arraybuffer”的功能。

    根据上面的文章,我将我的 js 函数更改为这个并且它可以工作:

    var form = $('<form method="post"></form>');
    for (var i in data) {
        form.append('<input name="'+i+'" value="'+data[i]+'" />');
    }
    
    data = form.serialize();
    
    var oReq = new XMLHttpRequest();
    oReq.open('POST', 'http://example.com/download.action', true);
    oReq.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    oReq.responseType = "arraybuffer";
    
    oReq.onload = function (oEvent) {
        var arrayBuffer = oReq.response;
        if (arrayBuffer) {
            var xhr = new XMLHttpRequest;
            xhr.open("POST", 'http://localhost/getpdf.php', false);
            xhr.send(arrayBuffer);
        }
    };
    
    oReq.send(data);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-11
      • 2012-05-11
      • 2015-09-19
      • 1970-01-01
      • 2022-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多