使用 Guzzle 6 将文件上传到 API 端点
Upload file using Guzzle 6 to API endpoint
我可以使用 Postman 将文件上传到 API 端点。
我正在尝试将其转换为从表单上传文件,使用 Laravel 上传文件并使用 Guzzle 6.
发布到端点
在 Postman 中的截图(我故意省略了 POST URL)
下面是当你点击 POSTMAN 中的 "Generate Code" link 时它生成的文本:
POST /api/file-submissions HTTP/1.1
Host: strippedhostname.com
Authorization: Basic 340r9iu34ontoeioir
Cache-Control: no-cache
Postman-Token: 6e0c3123-c07c-ce54-8ba1-0a1a402b53f1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="FileContents"; filename=""
Content-Type:
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="FileInfo"
{ "name": "_aaaa.txt", "clientNumber": "102425", "type": "Writeoff" }
----WebKitFormBoundary7MA4YWxkTrZu0gW
下面是保存文件和其他信息的控制器函数。文件上传正确,我可以获取文件信息。
我认为我遇到的问题是使用正确的数据设置多部分和 headers 数组。
public function fileUploadPost(Request $request)
{
$data_posted = $request->input();
$endpoint = "/file-submissions";
$response = array();
$file = $request->file('filename');
$name = time() . '_' . $file->getClientOriginalName();
$path = base_path() .'/public_html/documents/';
$resource = fopen($file,"r") or die("File upload Problems");
$file->move($path, $name);
// { "name": "test_upload.txt", "clientNumber": "102425", "type": "Writeoff" }
$fileinfo = array(
'name' => $name,
'clientNumber' => "102425",
'type' => 'Writeoff',
);
$client = new \GuzzleHttp\Client();
$res = $client->request('POST', $this->base_api . $endpoint, [
'auth' => [env('API_USERNAME'), env('API_PASSWORD')],
'multipart' => [
[
'name' => $name,
'FileContents' => fopen($path . $name, 'r'),
'contents' => fopen($path . $name, 'r'),
'FileInfo' => json_encode($fileinfo),
'headers' => [
'Content-Type' => 'text/plain',
'Content-Disposition' => 'form-data; name="FileContents"; filename="'. $name .'"',
],
// 'contents' => $resource,
]
],
]);
if($res->getStatusCode() != 200) exit("Something happened, could not retrieve data");
$response = json_decode($res->getBody());
var_dump($response);
exit();
}
我收到的错误,使用 Laravel 的调试视图显示的屏幕截图:
您发布数据的方式有误,因此收到的数据格式不正确。
The value of multipart
is an array of associative arrays, each
containing the following key value pairs:
name
: (string, required) the form field name
contents
:(StreamInterface/resource/string, required) The data to use in the
form element.
headers
: (array) Optional associative array of custom headers to use with the form element.
filename
: (string) Optional
string to send as the filename in the part.
使用上述列表之外的键并设置不必要的 headers 而不将每个字段分隔到一个数组中将导致发出错误的请求。
$res = $client->request('POST', $this->base_api . $endpoint, [
'auth' => [ env('API_USERNAME'), env('API_PASSWORD') ],
'multipart' => [
[
'name' => 'FileContents',
'contents' => file_get_contents($path . $name),
'filename' => $name
],
[
'name' => 'FileInfo',
'contents' => json_encode($fileinfo)
]
],
]);
$body = fopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);
http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=file
在 Laravel 8 with guzzle 我正在使用这个:
想法是你正在用 fread 或 file_get_content 读取文件,然后你可以使用 Laravel getPathname() 指向 /tmp
中的文件
$response = $this
->apiClient
->setUserKey($userToken)
->post(
'/some/url/to/api',
[
'multipart' => [
'name' => 'avatar',
'contents' => file_get_contents($request->file('avatar')->getPathname()),
'filename' => 'avata.' . $request->file('avatar')->getClientOriginalExtension()
]
]
);
我可以使用 Postman 将文件上传到 API 端点。
我正在尝试将其转换为从表单上传文件,使用 Laravel 上传文件并使用 Guzzle 6.
发布到端点在 Postman 中的截图(我故意省略了 POST URL)
下面是当你点击 POSTMAN 中的 "Generate Code" link 时它生成的文本:
POST /api/file-submissions HTTP/1.1
Host: strippedhostname.com
Authorization: Basic 340r9iu34ontoeioir
Cache-Control: no-cache
Postman-Token: 6e0c3123-c07c-ce54-8ba1-0a1a402b53f1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="FileContents"; filename=""
Content-Type:
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="FileInfo"
{ "name": "_aaaa.txt", "clientNumber": "102425", "type": "Writeoff" }
----WebKitFormBoundary7MA4YWxkTrZu0gW
下面是保存文件和其他信息的控制器函数。文件上传正确,我可以获取文件信息。
我认为我遇到的问题是使用正确的数据设置多部分和 headers 数组。
public function fileUploadPost(Request $request)
{
$data_posted = $request->input();
$endpoint = "/file-submissions";
$response = array();
$file = $request->file('filename');
$name = time() . '_' . $file->getClientOriginalName();
$path = base_path() .'/public_html/documents/';
$resource = fopen($file,"r") or die("File upload Problems");
$file->move($path, $name);
// { "name": "test_upload.txt", "clientNumber": "102425", "type": "Writeoff" }
$fileinfo = array(
'name' => $name,
'clientNumber' => "102425",
'type' => 'Writeoff',
);
$client = new \GuzzleHttp\Client();
$res = $client->request('POST', $this->base_api . $endpoint, [
'auth' => [env('API_USERNAME'), env('API_PASSWORD')],
'multipart' => [
[
'name' => $name,
'FileContents' => fopen($path . $name, 'r'),
'contents' => fopen($path . $name, 'r'),
'FileInfo' => json_encode($fileinfo),
'headers' => [
'Content-Type' => 'text/plain',
'Content-Disposition' => 'form-data; name="FileContents"; filename="'. $name .'"',
],
// 'contents' => $resource,
]
],
]);
if($res->getStatusCode() != 200) exit("Something happened, could not retrieve data");
$response = json_decode($res->getBody());
var_dump($response);
exit();
}
我收到的错误,使用 Laravel 的调试视图显示的屏幕截图:
您发布数据的方式有误,因此收到的数据格式不正确。
The value of
multipart
is an array of associative arrays, each containing the following key value pairs:
name
: (string, required) the form field name
contents
:(StreamInterface/resource/string, required) The data to use in the form element.
headers
: (array) Optional associative array of custom headers to use with the form element.
filename
: (string) Optional string to send as the filename in the part.
使用上述列表之外的键并设置不必要的 headers 而不将每个字段分隔到一个数组中将导致发出错误的请求。
$res = $client->request('POST', $this->base_api . $endpoint, [
'auth' => [ env('API_USERNAME'), env('API_PASSWORD') ],
'multipart' => [
[
'name' => 'FileContents',
'contents' => file_get_contents($path . $name),
'filename' => $name
],
[
'name' => 'FileInfo',
'contents' => json_encode($fileinfo)
]
],
]);
$body = fopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);
http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=file
在 Laravel 8 with guzzle 我正在使用这个:
想法是你正在用 fread 或 file_get_content 读取文件,然后你可以使用 Laravel getPathname() 指向 /tmp
中的文件 $response = $this
->apiClient
->setUserKey($userToken)
->post(
'/some/url/to/api',
[
'multipart' => [
'name' => 'avatar',
'contents' => file_get_contents($request->file('avatar')->getPathname()),
'filename' => 'avata.' . $request->file('avatar')->getClientOriginalExtension()
]
]
);