Laravel HTTP 客户端 - 将 XML 文件发布为 application/octet-stream

Laravel HTTP Client - Posting XML file as application/octet-stream

我正在尝试 post 到接受 XML 文件的外部 API。内容类型为 application/octet-stream.

这是我的代码:

return Http::withToken(config('sproom.auth_token'))
    ->withHeaders([
        'Content-Type' => 'application/octet-stream'
    ])
    ->attach('xml', file_get_contents('myfile.xml'), 'myfile')
    ->post('https://example.org/api/documents')->json();

当 post 执行上述操作时,我收到 API 错误返回:Cannot find format for document。不存在进一步的文档。

我猜测 xml 文件未正确发送为 application/octet-stream

外部 API 使用 Swagger 作为“文档”,如果我使用 Swagger UI 上传 XML 文件,我会收到成功响应。在 cURL 中:

curl -X POST "https://example.org/api/documents" -H  "accept: */*" -H  "Authorization: Bearer vmFrxk2+7......." -H  "Content-Type: application/octet-stream" -d {}

我不确定我做错了什么?

我不认为请求的内容类型是application/octet-stream,而且在你上面写的curl请求中有一个-d

curl -X POST "https://example.org/api/documents" -H  "accept: */*" -H  "Authorization: Bearer vmFrxk2+7......." -H  "Content-Type: application/octet-stream" -d {}

这是man curl中写的

-d, --data (HTTP) Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the server using the content-type application/x-www-form-urlencoded. Compare to -F, --form.

如果您使用的是->attach,我猜请求应该是multipart/form-data。 所以请看看你需要哪一个我猜你不能在 application/x-www-form-urlencoded.

中 post 文件

我认为目前在 attach() 中没有将内容类型附加到文件的选项,因此您可以尝试直接使用 guzzle。它默认带有 laravel 并且 httpclient 是它的包装器以减少代码。

这里是直接喷码

$client = new \GuzzleHttp\Client(['headers' => ['Authorization' => 'Bearer ' . config('sproom.auth_token')]]);
$client->request('POST', 'https://example.org/api/documents', [
    'headers' => [
        'Accept'     => '*/*'
    ],
    'multipart' => [
        [
            'name'     => 'myfile',
            'contents' => file_get_contents('myfile.xml'),
            'headers'  => ['Content-Type' => 'application/octet-stream'],
            'filename' => 'myfile.xml'
        ]
    ]
]);

最终,我最终直接使用了 Guzzle:

$client = new \GuzzleHttp\Client(['headers' => ['Authorization' => 'Bearer ' . config('sproom.auth_token')]]);
try {
    return $client->request('POST', config('sproom.api_url') . '/api/documents', [
        'body' => file_get_contents('myfile.xml'),
        'headers' => [
            'Content-Type' => 'application/json',
        ]
    ])->getBody();
} catch (RequestException $exception) {
    return json_decode($exception->getResponse()->getBody()->getContents());
}