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

时间:2023-01-27 12:03:28

I am able to upload a file to an API endpoint using Postman.

我可以使用Postman将文件上传到API端点。

I am trying to translate that into uploading a file from a form, uploading it using Laravel and posting to the endpoint using Guzzle 6.

我试图将其转换为从表单上传文件,使用Laravel上传并使用Guzzle 6发布到端点。

Screenshot of how it looks in Postman (I purposely left out the POST URL) 使用Guzzle 6将文件上传到API端点

它在Postman中的样子截图(我故意省略了POST URL)

Below is the text it generates when you click the "Generate Code" link in POSTMAN:

下面是您在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

Below is controller function for saving the file and other info. The file uploads correctly, I am able to get the file info.

以下是用于保存文件和其他信息的控制器功能。文件上传正确,我可以获取文件信息。

I think the problem I am having is setting the multipart and headers array with the correct data.

我认为我遇到的问题是使用正确的数据设置multipart和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();
}

The error I am receiving, screenshot of how it displays using Laravel's debugging view:

我收到的错误,使用Laravel的调试视图显示它的显示截图:

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

2 个解决方案

#1


20  

The way you are POSTing data is wrong, hence received data is malformed.

POST数据的方式是错误的,因此收到的数据格式不正确。

Guzzle docs:

Guzzle文档:

The value of multipart is an array of associative arrays, each containing the following key value pairs:

multipart的值是一个关联数组数组,每个数组包含以下键值对:

name: (string, required) the form field name

name :(字符串,必填)表单字段名称

contents:(StreamInterface/resource/string, required) The data to use in the form element.

contents:(StreamInterface / resource / string,required)要在表单元素中使用的数据。

headers: (array) Optional associative array of custom headers to use with the form element.

headers:(array)与表单元素一起使用的自定义标头的可选关联数组。

filename: (string) Optional string to send as the filename in the part.

filename:(string)作为文件名发送的可选字符串。

Using keys out of above list and setting unnecessary headers without separating each field into one array will result in making a bad request.

使用上面列表中的键并设置不必要的标题而不将每个字段分成一个数组将导致发出错误的请求。

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

#2


0  

$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

http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=file

#1


20  

The way you are POSTing data is wrong, hence received data is malformed.

POST数据的方式是错误的,因此收到的数据格式不正确。

Guzzle docs:

Guzzle文档:

The value of multipart is an array of associative arrays, each containing the following key value pairs:

multipart的值是一个关联数组数组,每个数组包含以下键值对:

name: (string, required) the form field name

name :(字符串,必填)表单字段名称

contents:(StreamInterface/resource/string, required) The data to use in the form element.

contents:(StreamInterface / resource / string,required)要在表单元素中使用的数据。

headers: (array) Optional associative array of custom headers to use with the form element.

headers:(array)与表单元素一起使用的自定义标头的可选关联数组。

filename: (string) Optional string to send as the filename in the part.

filename:(string)作为文件名发送的可选字符串。

Using keys out of above list and setting unnecessary headers without separating each field into one array will result in making a bad request.

使用上面列表中的键并设置不必要的标题而不将每个字段分成一个数组将导致发出错误的请求。

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

#2


0  

$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

http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=file