Open FernetB opened 2 years ago
Hey @FernetB. Have you considered using Http.uploadFile
?
Yes, but not only doesn't work but also ask the user for permissions to the file system.
@thomasvidas I'm doing something wrong ? With axios this works perfectly, but I really need to use this plugin for set-cookie
reasons with capacitor
On web: On Native:
Currently on Holiday, but I'm planning on fixing this in the 2.x
branch; which isn't released yet. Http.request
doesn't work with multipart form data. If someone else wants to make a PR I can review/release but I don't have the bandwidth to work on this.
Can I use uploadFile
for this? I tried and failed but maybe I did something wrong, or is just made for another purposes?
I am having the same issue, is it fixed as yet?
Nop, I have to change to axios
and use a clouflare worker to handle the set-cookie
and cors
problems
any updates?
Any news ? Is there any way besides FormData to send multiple files at once ?
Hi ! This is really a critical serious issue. It should be easy to use a form and send images with POST.
I won't let you all down, as I have a fix, but this issue should be resolved ASAP in my honest opinion.
So the fix idea is to get your image as dataURI in Ionic and send it as a string. This gives lot of problems really, and should be a fix only for a short period of time.
So, using this capacitor Http plugin, you will need first to convert the image in input to a DataURI. You will need fileReader and you will probably encounter another problem of capacitor, not loading the filereader properly.
So on Ionic app (interface side) you will need :
the fn to get fileReader
export function getFileReader(): FileReader {
const fileReader = new FileReader();
const zoneOriginalInstance = (fileReader as any)["__zone_symbol__originalInstance"];
return zoneOriginalInstance || fileReader;
};
the fn to get the dataURI from fileReader
export function readURL(file: any){
return new Promise((res, rej) => {
const reader = getFileReader();
reader.onload = e => res(e.target.result);
reader.onerror = e => rej(e);
reader.readAsDataURL(file);
});
};
the function to submit your data
async submit(){
const img = this.imgInput.nativeElement.files.item(0); // get the file from the input
const dataURI = await readURL(img); // get the dataURI with readURL function
await Http.request({ // post the file
method: 'post',
url: 'your/api/url/to/post/file',
data : {img: dataURI}
headers: {'Content-Type': 'application/json'}
});
}
of course you will also need to get the imgInput reference, so add the @ViewChild in your .ts file
@ViewChild('imgInput' , { static: true }) imgInput: ElementRef<HTMLInputElement>;
on html side you will need the input and a button
<input #imgInput name="img" type="file" accept="image/*">
<button (click)="submit()">submit image</button>
Then on api side, you will need to get the string from the body and to convert it to a base64 data that can be written as a file.
you will need a getDataURI fn :
export function getDataURI(base64: string): {type: string , ext: string , data: string}{
let type = '';
let ext = '';
let data = '';
for(let i = 0 ; i < 60 ; i++){
if(base64[i] === ':') {
for(let j = 1 ; j < 60 ; j++) {
if(base64[i+j] !== '/') {
type = type + base64[i+j];
} else {
break;
}
}
}
if(base64[i] === '/') {
for(let j = 1 ; j < 60 ; j++) {
if(base64[i+j] !== ';') {
ext = ext + base64[i+j];
} else {
break;
}
}
}
if(base64[i] === ',') {
data = base64.substr(i + 1);
break;
}
}
return {type , ext , data}
}
then you will have to get the data and write them using Buffer (on nodejs app)
const infos = getDataURI(body.img); // we get the img from {img: dataURI} POST in ionic interface
writeFileSync(resolve('./imgFile.jpg') , Buffer.from(infos.data , 'base64')
Now with this you will probably get payload too large error if your server can't handle big POST requests (statusCode: 413)
I am personally using loopback 4 + dokku (so nginx). If you get this error, you will need to make your payload bigger on your server and on your app.
sudo nano /etc/nginx/nginx.conf
// change line tp your needs => client_max_body_size 2M;
// for example client_max_body_size 200M;
// then save file and reload nginx
nginx -s reload
app.bind(RestBindings.REQUEST_BODY_PARSER_OPTIONS).to({limit: '200Mb'})
So yeah... this works but it's kinda horrible to just upload a file... And this will get out of hand with many files, you will have to handle a sort of lazy uploading. You could also try to stream files, or use websockets to send chunks... but yeah, this shouldn't be normal usage of Http imo.
Currently on Holiday, but I'm planning on fixing this in the
2.x
branch; which isn't released yet.Http.request
doesn't work with multipart form data. If someone else wants to make a PR I can review/release but I don't have the bandwidth to work on this.
@thomasvidas Hi Thomas ! Could we have some infos about what could be wrong in the capacitor Http plugin not sending properly FormData with files using POST method ? So we can try to fix the problem and send a pull request ?
Thank you a lot.
You can't send form data because it's not yet implemented. We need to wait until he or someone who knows Java and Swift adds it
El vie., 28 de enero de 2022 6:42 a. m., mightytyphoon < @.***> escribió:
Currently on Holiday, but I'm planning on fixing this in the 2.x branch; which isn't released yet. Http.request doesn't work with multipart form data. If someone else wants to make a PR I can review/release but I don't have the bandwidth to work on this.
@thomasvidas https://github.com/thomasvidas Hi Thomas ! Could we have some infos about what could be wrong in the capacitor Http plugin not sending properly FormData with files using POST method ? So we can try to fix the problem and send a pull request ?
Thank you a lot.
— Reply to this email directly, view it on GitHub https://github.com/capacitor-community/http/issues/213#issuecomment-1024045814, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALJFPIBMCA3BQ7Z7LMXGPBTUYJQHRANCNFSM5K4V45UQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
You are receiving this because you were mentioned.Message ID: @.***>
@FernetB I could give it a go. (I need to put the project I am working on in production in about 3 months, and I don't want to use my fix to send files in prod)
I bet for Android I need to do something with this file : https://github.com/capacitor-community/http/blob/main/android/src/main/java/com/getcapacitor/plugin/http/FormUploader.java and for iOS : https://github.com/capacitor-community/http/blob/main/ios/Plugin/HttpRequestHandler.swift
What I want is just someone to explain the possible problem(s) to try to fix it, this will help me to not lose too much time searching for the logic in the code.
I am into typescript and C++ everyday, but I am pretty language agnostic, so I could be able to understand how to send a formData using Java & Swift.
Here is a possible Java implementation : https://stackoverflow.com/questions/16797468/how-to-send-a-multipart-form-data-post-in-android-with-volley And here is a possible Swift implementation : https://stackoverflow.com/questions/43492089/how-to-send-form-data-in-post-request-in-swift-3
Edit : Hi, because this repo is unfinished and seems already dead, I finally abandoned @capacitor/http and ended using Axios instead to be able to use http only cookies and post forms.
Bye.
Hi, I finally ended using Axios to use http only cookies and post forms.
Bye.
When I've read this the first time (the "ended using axios" part) I thought it's something like "I'm done with axios, enough is enough". I understood it wrong and axios is the solution. I'm leaving this comment for other non native English speakers that may get confused as well.
Will there be a fix for the FormData ? Axios is not a solution for some of us and using FormData seems like an essential part of a HTTP plugin.
@modvd if you want to use cookies for persisting sessions and also formData, you don't have any other solution, check this repo, it's dead anyway. There is no more feedbacks on PR, only one guy has the hand on the repo and seems dead, so I don't think you should keep using this anyway. Either make your own or use Axios.
What I advise you to do is to create a http service inside your Ionic/Capacitor project, that will normalize the http requests. Meaning if one day this repo gets back on its feet, or you find something better than axios, you can only change one file to implement a new way of making the http requests in your app.
import { Injectable } from '@angular/core';
import { AxiosRequestConfig , default as http } from 'axios';
@Injectable({
providedIn: 'root'
})
export class HttpService {
constructor() { }
public async get(url: string , config: AxiosRequestConfig){
return await http.get(url , config);
}
public async post(url: string , body: any , config: AxiosRequestConfig){
return await http.post(url , body , config);
}
public async delete(url: string , config: AxiosRequestConfig){
return await http.delete(url , config);
}
public async head(){}
public async put(){}
}
Of course this can be pumped up by adding typings, as well as Observable.
Just got my whole app stop to function because i use, this lib as custom fetcher for Supabase, and they made the storage API use the custom fetcher last week. i will have a check and do a PR maybe next week if i have time Edit i didn't found a way to fix the module, and it's going to get deprecated in v4 in the meantime i found a solution for my use case in Supabase
export const useSupabase = () => {
const options: SupabaseClientOptions = {
fetch: (requestInfo, requestInit) => {
const url = requestInfo.toString()
if (requestInit?.method === 'POST' && url.includes('/storage/')) {
return fetch(requestInfo, requestInit)
}
return Http.request({
url,
method: requestInit?.method,
headers: requestInit?.headers as any || {},
data: requestInit?.body,
})
.then((data) => {
const type = data.headers['content-type']
const res = type.includes('application/vnd.pgrst.object+json') ? data.data : JSON.stringify(data.data)
const resp = new Response(res, {
status: data.status,
headers: data.headers,
})
return resp
})
},
}
return createClient(supabaseUrl, supabaseAnonKey, options)
}
+1
This is also a big problem for us as well. Has there been no progress yet?
@FernetB or @mightytyphoon Is there a Capacitor plugin that you used to implement Axios or just the normal JS lib?
This is also a big problem for us as well. Has there been no progress yet?
@FernetB or @mightytyphoon Is there a Capacitor plugin that you used to implement Axios or just the normal JS lib?
Hi, I created a http service file that handles all http requests (patch, post, get, etc...) with parameters, for now I have just 3 apps using this, so I don't need to create a package for easy management but I would advise to do so. This way if one day you need to change http and use this plugin, in case it's patched, you can easily change only the file once and this will work on all your projects by a simple update.
And yes, axios, you simply need to install it in your project with npm. It works seemlessly, don't forget to use withCredentials=true to send cookies during authenticated requests.
Axios was not a good solution for me in my Ionic app. I ended up going back to the cordova http plugin "cordova-plugin-advanced-http" which works great with FormData.
Axios was not a good solution for me in my Ionic app. I ended up going back to the cordova http plugin "cordova-plugin-advanced-http" which works great with FormData.
Could you explain why, please ?
Axios was not a good solution for me in my Ionic app. I ended up going back to the cordova http plugin "cordova-plugin-advanced-http" which works great with FormData.
Could you explain why, please ?
Because of the CORS restrictions when developing and running the app on a device.
Axios was not a good solution for me in my Ionic app. I ended up going back to the cordova http plugin "cordova-plugin-advanced-http" which works great with FormData.
Could you explain why, please ?
Because of the CORS restrictions when developing and running the app on a device.
Oh yeah right, I had this problem also, you have to manage them yourself on server side. Can be annoying indeed but it works.
I am facing same issue with this plugin. I tried implementing @ionic-native/http/ngx or cordova-plugin-advanced-http, project builds successfully. But in execution post methods doesn't get called or throws any exception.
Please fix capacitor-comminuty/http asap!!
I am facing same issue with this plugin. I tried implementing @ionic-native/http/ngx or cordova-plugin-advanced-http, project builds successfully. But in execution post methods doesn't get called or throws any exception.
Please fix capacitor-comminuty/http asap!!
Would love to make a PR and fix this, (to do so you just need to code the formData functionality both under swift of iOS and java for android, then create the interface for execution under js/typescript), but repo master isn't responding at all nor looking at PRs...
So imo best way is to use axios, which works great, but as pointed out by @modvd you will need to manage CORS server side.
@mightytyphoon @rsushant the repo admin is working on 100% compatible solution to integrate into Capacitor core as mentioned in the README : https://github.com/capacitor-community/http#maintence-mode Be patient better is coming :) There issue to follow also https://github.com/ionic-team/capacitor/issues/5145
@mightytyphoon @rsushant the repo admin is working on 100% compatible solution to integrate into Capacitor core as mentioned in the README : https://github.com/capacitor-community/http#maintence-mode
Be patient better is coming :)
Yeah sure, the guy came like 4 months ago, just to put one line in The readme and ignore all messages and community's PRs...
Still nothing?
Describe the bug I'm trying to do a post with a img file in a
FormData
and the request sends nothingSteps to reproduce
Expected behavior To send the formData
Screenshots