Как отправить файл и данные JSON на сервер - PullRequest
0 голосов
/ 15 января 2019

ТЛ; др : Используя 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, но я не могу понять, как заставить это работать.

Ответы [ 2 ]

0 голосов
/ 26 марта 2019

Вы можете получить свой JSON, как сказал @ Błażej Kowalczyk

$this->request->getPost()

и вы можете проверить файлы и получить их

if ($this->request->hasFiles()) {
    foreach ($this->request->getUploadedFiles() as $file) {
        // $file is an instance of Phalcon\Http\Request\File
        var_dump($file->getName());
    }
}

проверьте эти страницы для получения дополнительной информации https://docs.phalconphp.com/3.4/en/api/phalcon_http_request https://docs.phalconphp.com/3.4/en/api/phalcon_http_request_file

0 голосов
/ 15 января 2019

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

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