Как отправить файл и данные JSON на сервер

ТЛ; др:
Используя Angular 6 на внешнем интерфейсе и PHP с Phalcon на внутреннем, я могу отправлять данные JSON или же Файл без проблем, но у меня проблема с отправкой обоих в одном запросе.


Ранее я отправлял данные JSON на сервер, используя что-то вроде этого

const HTTP_OPTIONS = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
}),
observe: 'response'
};

post(endPoint: string, body: object): Observable<any> {
return this.http.post<any>(this.apiUrl + endPoint, body, HTTP_OPTIONS)
.pipe(
tap(result => this.log(JSON.stringify(result, null, 2))),
catchError(this.handleError('post', []))
);
}

И я смог получить данные из PHP с помощью Phalcon с

$app = new \Phalcon\Mvc\Micro();
$app->post('/upload', function() use ($app) {

$input = $app->request->getJsonRawBody();
// $input now contains my JSON data
});

Через некоторое время мне нужно было отправить файл, поэтому я использовал этот ответ с некоторыми незначительными изменениями:

postFile(fileToUpload: File, endpoint: string): Observable<any> {
const formData: FormData = new FormData();
formData.append('fileKey', fileToUpload, fileToUpload.name);
return this.httpClient
.post(endpoint, formData, { headers: {'Authorization': this.jwt} }).pipe(
tap(result => this.log(JSON.stringify(result, null, 2))),
catchError(this.handleError('post', []))
);
}

И я получил свой файл без проблем, используя документация в качестве руководства:

$app->post('/uploads', function() use ($app) {
if ($app->request->hasFiles() == true) {
foreach ($app->request->getUploadedFiles() as $file) {
$file->moveTo('files/' .$file->getname());
}
} else {
$app->response->setStatusCode(400)->sendHeaders();
$app->response->setJsonContent(['error' => 'no file']);
return $app->response;
}
});

Эта проблема: Теперь я хотел бы отправить файл и некоторые данные JSON одновременно. Я всегда могу просто загрузить файл и затем отправить данные отдельно, но я не думаю, что это правильный способ сделать это. Я не хочу совершать больше минимального количества сетевых вызовов.

Что я пробовал: Использование кода загрузки файла и просто добавление другого поля в мой объект FormData с моими данными JSON

formData.append('fileKey', fileToUpload, fileToUpload.name);
formData.append('data', JSON.stringify(data));

и вариация этого

formData.append('fileKey', fileToUpload, fileToUpload.name);
formData.append('data', new Blob([JSON.stringify(data), {type: 'application/json'}]);

В любом случае, на сервере я могу получить файл, но $app->request->getJsonRawBody а также $app->request->getRawBody пусты

Я также попытался использовать исходный код JSON-отправки и просто немного изменить, чтобы включить файл, но безуспешно.

post(fileToUpload: File, data: CustomData): Observable<any> {
this.messageService.add('uploaded file');

const formData: FormData = new FormData();
formData.append('fileKey', fileToUpload, fileToUpload.name);
formData.append('data', JSON.stringify(data), 'data');

return this.http
.post(this.apiUrl + 'uploads/', {'data': data, 'file': fileToUpload}, HTTP_OPTIONS).pipe( // file is empty on the server like this
tap(result => this.log('POST file :\n' + JSON.stringify(result, null, 2))),
catchError(this.handleError('post', [], 'fileUpload'))
);
}

Я могу легко отправить мои данные JSON или файл, но не оба одновременно.
Я искал документацию Phalcon и несколько QA по отправке файлов и / или JSON с Angular, но я не могу понять, как заставить это работать.

1

Решение

Вы отправляете json как текст в пост-запросе, поэтому вместо $ app-> request-> getJsonRawBody вы должны попробовать что-то вроде

$rawJson=$app->request->getPost('data');
$object=json_decode($rawJson);
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector