web-dev-qa-db-de.com

Datei mit Guzzle 6 zum API-Endpunkt hochladen

Ich kann mit Postman eine Datei auf einen API-Endpunkt hochladen.

Ich versuche, dies in das Hochladen einer Datei aus einem Formular zu übersetzen, mit Laravel hochzuladen und mit Guzzle 6 an den Endpunkt zu senden.

Screenshot, wie es in Postman aussieht (ich habe die URL POST absichtlich weggelassen)  enter image description here

Der folgende Text wird generiert, wenn Sie in POSTMAN auf den Link "Code generieren" klicken:

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

Nachfolgend finden Sie eine Controller-Funktion zum Speichern der Datei und anderer Informationen. Die Datei wird korrekt hochgeladen, ich kann die Dateiinformationen abrufen.

Ich denke, das Problem, das ich habe, besteht darin, das Multipart- und Header-Array mit den korrekten Daten zu setzen.

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();
}

Der Fehler, den ich erhalte, Screenshot, wie er in der Debugging-Ansicht von Laravel angezeigt wird:

 enter image description here

20
Brad

Die Art und Weise, in der Sie die POST-Daten senden, ist falsch, daher werden empfangene Daten fehlerhaft dargestellt.

Guzzle-Dokumente :

Der Wert von multipart ist ein Array von assoziativen Arrays, jeweils mit folgenden Schlüsselwertpaaren:

name: (Zeichenfolge, erforderlich) Name des Formularfelds

contents :( StreamInterface/resource/string, erforderlich) Die Daten, die in .__ verwendet werden sollen. Formularelement.

headers: (array) Optionales assoziatives Array von benutzerdefinierten Headern, das mit dem Formularelement verwendet werden kann.

filename: (string) Optional String, der als Dateiname im Teil gesendet werden soll.

Die Verwendung von Schlüsseln aus der obigen Liste und das Festlegen unnötiger Header, ohne dass jedes Feld in ein Array unterteilt werden muss, führt zu einer fehlerhaften Anforderung.

$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)
        ]
    ],
]);
32
revo
$body = fopen('/path/to/file', 'r');
$r = $client->request('POST', 'http://httpbin.org/post', ['body' => $body]);

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

0
Pawel