I have a simple todos application in which i am trying to upload a photo along with a single todo. Now i have created this factory function that takes care of the creation of the todo
todosFactory.insertTodo = function(todo){
return $http.post(baseUrl, todo, {
headers: {
'Content-Type' : undefined
},
transformRequest: function(data, headersGetter){
var formData = new FormData();
angular.forEach(data, function (value, key) {
formData.append(key, value);
});
return formData;
}
});
};
And the factory update method looks like this
todosFactory.updateTodo = function(id, todo){
return $http.put(baseUrl + '/' + id, todo, {
headers: {
'Content-Type' : undefined
},
transformRequest: function(data, headersGetter){
var formData = new FormData();
angular.forEach(data, function (value, key) {
formData.append(key, value);
});
return formData;
}
});
};
The insertTodo is working as expected but the updateTodo is not posting data to the server. I am using laravel for the API and the update API endpoint has this code
dd(Input::all(), Input::file('cover_photo'));
This shows that noting was posted in the request. And if i change the put to post in the updateTodo factory method it starts working. Am i missing some extra headers or something ?
If i remove both the transformRequest
and headers
form the updateTodo method, the text data is successfully received on the server but the the file doesn’t.
And if i just remove the headers
nothing gets posted
I am using the PHP server that comes with laravel using this command
php artisan serve
Thanks to @Ricardo's answer i was able to get the submitted data using this code
router->put('/todos/{id}', function($id){
$stream = file_get_contents("php://input");
echo $stream;
die();
});
I am getting the stream in this format
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="id"
5
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="name"
Image Todo
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="complete"
0
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="created_at"
2015-10-02 06:28:10
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="updated_at"
2015-10-02 06:28:10
-----------------------------3643739756006088191021064137
Content-Disposition: form-data; name="cover_photo"; filename="Dragon-Falls-Venezuela-5.jpg"
Content-Type: image/jpeg
�����JFIF��H�H������Exif��MM�*�����i������������������z���,����UNICODE��C�R�E�A�T�O�R�:�
�g�d�-�j�p�e�g� �v�1�.�0� �(�u�s�i�n�g� �I�J�G� �J�P�E�G� �v�6�2�)�,� �q�u�a�l�i�t�y� �=� �9�0�
Now i need to parse this raw format. I have found two php methods that other people have suggested http://php.net/manual/en/function.mb-parse-str.php and http://php.net/manual/en/function.parse-str.php but both of them are not working properly and do not give an array like $_GET or $_POST.
This piece from the PHP documentation discusses the PUT method and file uploads (multipart/form-data).
I can't quote any parts from it because I think everything is important. You should read it in detail but to summarize it's not possible without changes to your Apache configuration and creation of auxiliary scripts.
With Laravel you should use Form Method Spoofing (basically a variable called _method
) and keep on using POST. The _method
will allow you to call Laravel's PUT action correctly.
Edit
AngularJS, by default, sends data in the JSON format which explains why you cannot access the data with the $_POST
global. I have answered this in another question which explains what you have to do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With