When uploading from Angular 2, PHP fails to populate the $_POST and $_FILES variables

I'm encountering difficulties when trying to upload files and data to my server using Angular 2 and PHP.

After following the instructions in File Upload In Angular 2? to upload data and files from Angular 2, everything appears to be functioning correctly (I can confirm that the data is received by printing php://input). Here is an example of my Angular 2 code:

upload(data: data, file: File): Observable<any> {
  let header = new Headers();
  header.append('Content-Type', 'multipart/form-data');
  header.append('Accept', 'application/json');
  let options = new RequestOptions({ headers: header });

  let formData:FormData = new FormData();
  formData.append('file', file, file.name)
  formData.append('data', JSON.stringify({data}));

  return this.http
    .post('myurl', formData, options)
    .map(response => {
      return response;
    })
    .catch(error => Observable.throw(error.message || error));
}

The issue arises as the superglobals $_POST and $_FILES remain empty, thus preventing me from accessing the uploaded data and files. I faced a similar problem when only uploading data and resolved it by manually populating the $_POST superglobal as shown below:

$_POST = file_get_contents("php://input");

However, this method cannot be applied to handle $_FILES....

I came across a post PHP - empty $_POST and $_FILES - when uploading larger files suggesting that the issue could be related to post_max_size or upload_max_filesize being set too low. Despite setting them to 100M, the problem persists. I even increased memory_limit, but to no avail.

I suspect the root of the problem may lie in my server-side configuration, possibly due to the headers I've set or some missing settings. I have ruled out any CodeIgniter-related issues (as I am using the latest version of CodeIgniter) by attempting to post to a simple PHP file with the same outcome. The simplest server-side setup I tried includes:

<?php
  header('Content-Type: application/json');
  header('Access-Control-Allow-Origin: *');
  header('Access-Control-Allow-Methods: GET, POST');
  header('Access-Control-Allow-Headers: Content-Type');

  exit(var_dump($_POST, $_FILES));
?>

Despite this, I continue to receive empty arrays...

Is there anyone who has suggestions on how I can proceed?

Answer №1

After much searching, I have finally discovered the solution to this issue.

In simpler terms (as I am not an expert), when making an HTTP post multipart/form-data request, a random string boundary is used to differentiate between the various parameters sent by the client. This allows the server to properly parse the input. A correctly formatted request header will appear like so:

Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryYnNrniY34QSJ48LC

In my implementation, setting the request header as:

header.append('Content-Type', 'multipart/form-data');

resulted in no boundary being set, causing PHP to struggle with parsing the input and populating $_POST and $_FILES. Although attempting to define a custom boundary at the end of the header did not work initially, I eventually found a simple solution: there is no need to specify the Content-Type header at all. Angular 2 automatically generates the correct boundary when sending data as FormData in a post request, enabling PHP to utilize it effectively.

Therefore, the following code can be utilized:

upload(data: any, file: File): Observable<any> {
  let formData:FormData = new FormData();
  formData.append('file', file, file.name)
  formData.append('data', JSON.stringify({data}));

  return this.http
    .post('myurl', formData)
    .map(response => {
      return response;
    })
    .catch(error => Observable.throw(error.message || error));
}

Through executing this post request, Angular 2 handles the generation of a valid boundary within the multipart/form-data header automatically.

That concludes the explanation.

If anyone can provide additional technical insights on this topic, it would be greatly appreciated.

I hope this information proves helpful to others facing similar challenges.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to format text within the _e() function in WordPress?

As I work on developing a basic plugin, I encountered the following line of code: echo "<p style=\"color:red;\">Please enter a valid email address!</p>"; I aim to make this plugin easy to localize and internationa ...

Exploring Angular4: Utilizing HttpClient with HttpParams for Passing Object Values in httpParams.set()

I'm facing an issue with handling a more complex key value pair. What if I need to set a value as an object? This is the problem I am encountering: const includeStr = JSON.stringify({include: 'match-timeline-events'}); const params: HttpPa ...

Loading a form on the fly using jQuery

As I delve into the realm of web design, I encountered a perplexing issue that has left me stumped. My goal is to dynamically load a form into a div element using jQuery. Here's a snippet of my code: Inside the main file: $('#left_colum'). ...

PHP XML loop encountering issues with functionality

Hi there, I'm a newcomer to stackoverflow, but I've been following this site for quite some time. Currently, I'm working on a simple web application that will serve as a catalogue for music tracks, allowing users to add their own tracks afte ...

Ajax is coming back with a value that is not defined

Currently, I am working on a search function that is responsible for searching a name from the database. When the user clicks "add", the selected item should appear below the search field so that it can be saved in the database. However, I am encountering ...

Instructions for concealing and revealing a label and its corresponding field before and after making a choice from a dropdown menu

Currently, I am working on developing a form that will enable customers to input their order information. This form includes a selection list for payment methods, with three available options. If the user chooses either credit or debit card as the paymen ...

Setting up an Ionic 5.24 / Capacitor 2.0.1 / Angular 9.1.2 project to view TypeScript sources while debugging in AVD using Chrome DevTools

I'm having trouble configuring an Ionic (5.24) project to access the TypeScript sources while debugging on an Android Virtual Device using Chrome DevTools. Capacitor version: 2.0.1 Angular version: 9.1.2 Here's what I have tried: ionic cap ru ...

tips for creating a unique component with specialized features

I am struggling to integrate action buttons with specific actions in my custom component. It seems challenging to provide functions to my custom table, especially those that depend on the attributes of the table itself. You can take a look at this exampl ...

Avoiding timeouts through the transmission of $_POST data

I currently have a PHP file that contains an HTML form. When the submit button on the form is clicked, the PHP file receives two values via $_POST and proceeds to create some files which may take several minutes. I am concerned about potential timeouts as ...

What is the method for determining if an ngModel input field has been modified?

I'm currently working with this HTML template: <input type="text" ngModel #myValue="ngModel" name="{{ fieldName }}" id="{{ fieldName }}" value="{{ myVal }}" class="form-control" (change)="checkDirty(myValue)"> How can I determine ...

leveraging external libraries with angular

Is there a way to integrate third-party libraries into Angular 4? Typically, I follow the code snippet below: <html> <head> <title>Bootstrap CDN Simple Example</title> <link href="//netdna.bootstrapcdn.com/ ...

passing data through URL in Angular 7

Looking to pass a parameter in the URL while using Angular 7, to achieve a format like example.com/search/users?q=tom. Below is the syntax I am currently using in my service: public searchUsers(obj):any{ return this._http.get('example.com/s ...

NativeScript element isn't showing up

Being relatively new to application development with NativeScript, I find myself in a situation where I need assistance in finding a solution. Drawing from my experience with PHP, I am now looking to create a template for each "page" of the application. Th ...

What is the best way to combine and organize arrays in PHP using custom or user-specified criteria?

I am currently dealing with two arrays: $data1 = array( (0) => array("level" => 1, "id" => 1, "index" => 1, "amount" => 50000), (1) => array("level" => 1, "id" => 2, "index" => 1, "amount" => 40000), ...

"Can you provide guidance on how to access an array within another array

How do I retrieve data from Facebook Graph API such as [message] and [created_time]? Below is the JSON response I receive from Facebook Graph API: Array ( [posts] => Array ( [data] => Array ( [0] => Array ...

Creating a naming convention for constants in Angular schematics

I'm currently working on developing schematics for an Angular service that has a fixed name which cannot be modified by the user. Although I have eliminated all references to the 'name' variable, I encounter an error when attempting to util ...

Utilizing Filestack in Angular 2

I'm currently working on integrating image uploading functionality into my Angular 2 App, and I have decided to utilize Filestack (formerly filepicker.io) for storing the images. Following Filestack's recommendations, I added the necessary script ...

How to use an array of parameters with Yii2's createUrl() function?

As per the instructions provided in the Yii2 documentation, the recommended way to construct a URL is as follows: $appUrl = Yii::$app->urlManager->createUrl([Yii::$app->controller->id . '/' . Yii::$app->controller->action->i ...

Unable to connect to LAN Network with WampServer 3.2.3

I am having trouble accessing my WampServer machine. Here are my specifications: Windows 10 WampServer 3.2.3.3 64bits Apache 2.4.46 I made changes to the file "D:\Programs\wamp64\bin\apache\apache2.4.46\conf\extra\h ...

The Angular2 Router directs the user to the main Component

After configuring the Angular2 router and setting up the server (asp.net core) to redirect unknown paths to /index.html, the routing appears to be functioning properly. However, I am encountering an issue where visiting a specific URL (i.e. www.sitename.co ...