laravel 使用Guzzle 6将文件上传到API端点

zengzsys  于 2023-05-08  发布在  其他
关注(0)|答案(3)|浏览(199)

我能够使用Postman将文件上传到API端点。
我试图将其转换为从表单上传文件,使用Laravel上传并使用Guzzle 6发布到端点。
它在Postman中的外观截图(我故意省略了POST URL)

下面是当你点击POSTMAN中的“生成代码”链接时生成的文本:

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

下面是保存文件和其他信息的控制器功能。文件上传正确,我能够得到文件信息。
我认为我遇到的问题是用正确的数据设置multipart和header数组。

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的调试视图显示的屏幕截图:

ghhaqwfi

ghhaqwfi1#

您发布数据的方式是错误的,因此接收到的数据格式不正确。
狼吞虎咽文档:
multipart的值是一个关联数组的数组,每个数组包含以下键值对:
name:(字符串,必填)表单字段名称
contents:(StreamInterface/resource/string,required)表单元素中使用的数据。
headers:(array)可选的与form元素一起使用的自定义标题的关联数组。
filename:(string)可选字符串,作为部件中的文件名发送。
使用以上列表中的键并设置不必要的头,而不将每个字段分成一个数组,将导致发出错误的请求。

$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)
        ]
    ],
]);
x4shl7ld

x4shl7ld2#

$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

mwngjboj

mwngjboj3#

在Laravel 8中,我使用了这个:
这个想法是,您正在使用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()
                    ]
                ]
            );

相关问题