Laravel/Guzzle - POST 二进制文件内容
Laravel/Guzzle - POST binary file content
我正在尝试向第三方 API 发送一个简单的 POST 请求。 API 接受文件作为 BODY 参数。具体来说,文件内容必须是二进制的:
我已经使用 Postman 成功地 posted 到这个第 3 方 API,正文配置如下:
上传文件时,我使用的是Laravel。这是代码:
//$document is a class of "UploadedFile"
$tempfile = Storage::disk('local')->putFile('/temp', $document);
然后我只是尝试使用 Guzzle post 这个文件:
use Illuminate\Support\Facades\Http;
$filepath = storage_path('app/' . $tempfile);
$post = Http::attach('file', file_get_contents($tempfile), 'myfile.pdf')->post('example.org')->json());
但是,第 3 方 API 无法将其识别为 PDF 文件:
Content type must be one of application/vnd.hypatos.ocr+json application/pdf image/tiff image/jpeg image/png text/xml application/xml
与我在 Postman 中发送的请求相比,我做错了什么?它与我试图 post 到 API.
的文件完全相同
您是否试过在您的请求 headers 中像这样指定您的 Content-Type
Http::attach('file', file_get_contents($tempfile), 'myfile.pdf')->withHeaders([
'Content-Type' => 'application/pdf',
])->post('example.org')->json();
尝试直接从 postman 复制代码,看看您可能遗漏了什么。
所以这是一个很好的问题,因为处理二进制数据可能很棘手。我没有完全按照您的意愿进行操作,但是,我制作了一个 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;
}
});
这里有额外的处理进度条的内容,但它与处理二进制数据无关,所以我将跳过它。
现在我将文件解析为数组并对其进行处理,并希望 return 向用户提供电子表格,这是二进制 gigery pokery 开始的地方。当我 return 数据时,我必须将其编码为 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;
}
我知道这不是一次性的答案,但我确实希望您对使用二进制数据有所了解。
我正在尝试向第三方 API 发送一个简单的 POST 请求。 API 接受文件作为 BODY 参数。具体来说,文件内容必须是二进制的:
我已经使用 Postman 成功地 posted 到这个第 3 方 API,正文配置如下:
上传文件时,我使用的是Laravel。这是代码:
//$document is a class of "UploadedFile"
$tempfile = Storage::disk('local')->putFile('/temp', $document);
然后我只是尝试使用 Guzzle post 这个文件:
use Illuminate\Support\Facades\Http;
$filepath = storage_path('app/' . $tempfile);
$post = Http::attach('file', file_get_contents($tempfile), 'myfile.pdf')->post('example.org')->json());
但是,第 3 方 API 无法将其识别为 PDF 文件:
Content type must be one of application/vnd.hypatos.ocr+json application/pdf image/tiff image/jpeg image/png text/xml application/xml
与我在 Postman 中发送的请求相比,我做错了什么?它与我试图 post 到 API.
的文件完全相同您是否试过在您的请求 headers 中像这样指定您的 Content-Type
Http::attach('file', file_get_contents($tempfile), 'myfile.pdf')->withHeaders([
'Content-Type' => 'application/pdf',
])->post('example.org')->json();
尝试直接从 postman 复制代码,看看您可能遗漏了什么。
所以这是一个很好的问题,因为处理二进制数据可能很棘手。我没有完全按照您的意愿进行操作,但是,我制作了一个 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;
}
});
这里有额外的处理进度条的内容,但它与处理二进制数据无关,所以我将跳过它。
现在我将文件解析为数组并对其进行处理,并希望 return 向用户提供电子表格,这是二进制 gigery pokery 开始的地方。当我 return 数据时,我必须将其编码为 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;
}
我知道这不是一次性的答案,但我确实希望您对使用二进制数据有所了解。