I am submitting a form with fields like title
and description
using http.post
and it works fine. I also allow user to use the camera to capture a photo and save it as a string in base64
format. I need to submit this photo to the server via the same POST request. How can I do this? My code so far is as the following and the server looks for the uploaded photo in a field named “photo”:
headers = new Headers({'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'});
options = new RequestOptions({ headers: this.headers });
let data = {
title: item.title,
description: item.description
};
let params = new URLSearchParams();
for(let key in data){
params.set(key, data[key])
}
this.http.post('http://example.com/items', params.toString(), this.options).subscribe(
(result) => {
console.log("success!");
},
(err) => {
console.log(JSON.stringify(err));
}
);
1 Like
Anonymous sorry for post it
And how to include the photo in the POST request after doing that?
</> please ref following code.
this.signature = this.signaturePad.toDataURL();
sessionStorage.setItem("Signature", this.signature);
this.Base64Signature = this.signature.replace(/^data:image\/(png|jpg);base64,/, "");
var i = JSON.stringify({
Id: this.localId, DeliverymanId: this.localDeliverymanId, Image: this.Base64Signature , Qty: this.qty, Remarks: this.remarks, Status: this.Status,
Photo: this.Photo64, Reason: this.localReasonId, BusinessUnitId: this.BussinessUnitId, CreatedUserId: this.UserId, ModifiedUserId: this.UserId
});
None of this is ever necessary, and is in fact counterproductive, introduces opportunities for bugs, and makes code needlessly verbose and hard to read. Simply pass an object as the body payload and the content type will be set appropriately by Angular.
Ok I changed my code to this:
let data = {
title: item.title,
description: item.description,
photo: item.photo
};
this.http.post('http://example.com/items', data).subscribe(
(result) => {
console.log("success!");
},
(err) => {
console.log(JSON.stringify(err));
}
);
item.photo
is set this way:
const options: CameraOptions = {
quality: 100,
targetWidth: 800,
sourceType: this.camera.PictureSourceType.CAMERA,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
this.photo = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
console.log("error occured!");
});
The above code only submit the title
and description
fields though. No field named “photo” becomes available on the server side. The photo is captured correctly and I can show it in my app before submitting.
@Arulmano could you please elaborate on the sample code you have provided?
Are we certain that photo
is set at the time we are attempting to post it?
Here is the first think, the Photo string data is too long so send your data with JSON.stringify and getting that data as JSON(your Backend) and serialization it.
Yes, I logged it before calling http.post
and it’s a long string starting with data:image/jpeg;base64
. Is this how a file should be uploaded by POST request?
I suspect your problem is that you’re overflowing the URL length. www-form-encoded
puts everything in the query string. I think you are going to need whoever is in charge of the backend to switch to accepting JSON instead.
I changed the backend to accept JSON. What should I do now?
It’s really strange that there is no straight forward answer to this question. Am I the first one in the world of ionic who is trying to submit a file along with form data to server? 
Get rid of all the headers and requestoptions and URLSearchParams junk and just put the data URL in the data
object and pass data
itself as the payload to http.post()
. Angular will set the content type to application/json
for you.
I already did that. Look at my 3rd post in this thread. After that change, “photo” was not received in the backend.
I can’t tell what is going where because item
and data
are so vague, but the only place that you can rely on that photo
is inside the then
block, so you have to do all your posting from in there.
I log data.photo
before calling http.post
and it’s always a long string starting with data:image/jpeg;base64
. So rest assured that photo is not empty. Besides, in my application http.post
is never called immediately after the photo is taken, so there is no need to POST data in then
.
You can use the Network tab of Chrome’s developer tools to see what is going over the wire. That will tell you whether the problem is on the Ionic side or the server side. Server logs may also be relevant.
Ok I will do that. Also let me point out that I could upload the file and form data using File Transfer Plugin. The problem with file transfer plugin though is that it can only post one file at each request (It is actually equivalent to submitting a form which contains only one file).
@rapropos This is what is logged in the Network tab:
Request URL:http://192.168.1.102/items
Request Method:POST
Status Code:201 Created
Request Headers
Accept:application/json, text/plain, /
content-type:application/json
Origin:http://192.168.1.102:8100
Referer:http://192.168.1.102:8100/
User-Agent:Mozilla/5.0 (Linux; Android 4.4.2; LG-D802 Build/KOT49I.D80220c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36
Request Payload
{title:some-title, description:some-desc,…}
description: “some-desc”
photo: “data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBA…” => (very long string)
title: “some-title”
Response Headers
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://192.168.1.102:8100
Access-Control-Expose-Headers:*
Cache-Control:no-cache
Connection:Keep-Alive
Content-Length:0
Content-Type:text/html; charset=UTF-8
Date:Wed, 27 Sep 2017 21:07:25 GMT
Keep-Alive:timeout=5, max=100
Server:Apache/2.4.23 (Win64) PHP/5.6.25
Vary:Origin
X-Powered-By:PHP/5.6.25
That would seem to indicate that the Ionic side is doing its job, so I would shift to looking at blaming the server side.
What if I told you I posted the same parameters (title, description, photo) to the same URL using postman
and it was successful? I also posted the same parameters using ionic’s File Transfer plugin and it was successful too. So there is no doubt that the server side should not be blamed for this problem.