ТЛ; др:
Используя 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, но я не могу понять, как заставить это работать.
Вы отправляете json как текст в пост-запросе, поэтому вместо $ app-> request-> getJsonRawBody вы должны попробовать что-то вроде
$rawJson=$app->request->getPost('data');
$object=json_decode($rawJson);
Других решений пока нет …