Laravel / Guzzle-POST二进制文件内容

问题描述

我正在尝试向第三方API执行简单的POST请求。 API接受文件作为BODY参数。具体来说,文件内容必须为二进制:

enter image description here

我已使用Postman成功将其发布到此第三方API,并具有以下主体配置:

enter image description here

上传文件时,我正在使用Laravel。这是代码:

//$document is a class of "UploadedFile"
$tempfile = Storage::disk('local')->putFile('/temp',$document);

然后我只是尝试使用Guzzle发布此文件:

use Illuminate\Support\Facades\Http;

$filepath = storage_path('app/' . $tempfile);
$post = Http::attach('file',file_get_contents($tempfile),'myfile.pdf')->post('example.org')->json());

但是,第三方API无法将其识别为PDF文件:

内容类型必须为application / vnd.hypatos.ocr + json application / pdf图像/ tiff图像/ jpeg图像/ png文本/ xml应用程序/ xml之一

与我在邮递员中发送的请求相比,我做错了什么?这与我要发布到API的文件完全相同。

解决方法

您是否曾尝试在请求标头中指定Content-Type

Http::attach('file',file_get_contents($tempfile),'myfile.pdf')->withHeaders([
    'Content-Type' => 'application/pdf',])->post('example.org')->json();
,

尝试直接从邮递员复制代码,看看您可能会缺少什么。

所以这是一个好问题,因为处理二进制数据可能很棘手。我还没有完全完成您要尝试做的事情,但是,我制作了一个laravel页面,该页面上传电子表格流程,该流程会更改数据,然后弹出修改后的电子表格的下载内容。使用二进制文件是一个完全的痛苦,但这是我学到的。首先是基本表格。

<input id="file" type="file" class="form-control" name="file" style="height:auto;" required />

然后上传ajax

$.ajax({
            async: true,method: 'POST',enctype: 'multipart/form-data',processData: false,contentType: false,cache: false,url: "priceIncrease/parseHeaders",data: formData,xhr: function () {
                var myXhr = $.ajaxSettings.xhr();
                if (myXhr.upload) {
                    myXhr.upload.addEventListener('progress',progress,false);
                }
                return myXhr;
            }
        });

这里还有一些额外的功能可以处理进度条,但这与处理二进制数据无关,因此我将跳过它。

现在,我将文件解析为数组,然后对其进行处理,并希望将电子表格返回给用户,这是二进制巨额扑克开始的地方。当我返回数据时,我不得不将其编码为base64

$fqn = storage_path() . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . $priceIncreaseResult['filepath'] . $priceIncreaseResult['filename'];
$response = base64_encode(file_get_contents($fqn));

然后在前端,我给它设置了mime类型,并转换回了base64。

if(data['progress']['file']){
                var result = data['progress']['file'];
                var a = document.createElement("a");
                var file = document.getElementById("file");
                var filename = file.files[0].name;
                console.log(filename);
                var blob = new Blob([s2ab(atob(result))],{
                    type: 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,'
                });
                a.href = URL.createObjectURL(blob);
                a.download = filename;
                document.body.appendChild(a);
                a.click();
                a.remove();
            }

最后一件是类型转换

        function s2ab(s) {
        var buf = new ArrayBuffer(s.length);
        var view = new Uint8Array(buf);
        for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
        return buf;
    }

我知道这不是一个一次性的答案,但是,我希望您能对使用二进制数据有所启发。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...