如何将文件和JSON数据同时发送到服务器

时间:2019-01-14 22:47:36

标签: php angular upload phalcon angular-httpclient

tl; dr : 在前端使用Angular 6,在后端使用PHP和Phalcon,我可以毫无问题地发送JSON数据文件,但是在同一请求中发送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', []))
      );
}

我能够使用Phalcon从PHP获取数据

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

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

一段时间后,我需要发送文件,因此我使用了this answer并做了一些小的修改:

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', []))
      );
  }

使用the documentation作为指南,我收到的文件没有问题:

$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数据。我总是可以只上传文件,然后分别发送数据,但是我认为这不是正确的方法。我不想拨打超过网络通话次数的最小值。

我尝试过的操作:使用文件上传代码,只需将另一个字段和JSON数据附加到我的FormData对象中

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文档以及有关使用Angular发送文件和/或JSON的几个QA的信息,但我不知道该如何进行这项工作。

2 个答案:

答案 0 :(得分:0)

您要在发布请求中以文本形式发送json,因此应该尝试类似$ p-> request-> getJsonRawBody的方法

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

答案 1 :(得分:0)

您可以按照@BłażejKowalczyk所说的方式获取json

$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