amav96
January 18, 2024, 8:47pm
1
I am trying to make a fetch to google maps api
this is my httprequest controller
import { CapacitorHttp, HttpResponse, HttpHeaders } from '@capacitor/core';
import { Preferences } from '@capacitor/preferences';
export interface ApiRequest<T = any> {
url: string;
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
data?: T;
extraHeaders?: { [key: string]: string };
params?: { [key: string]: string };
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text' | 'document';
auth?: boolean;
}
export interface ApiResponse<T = any> {
data: T;
status: number;
headers: HttpHeaders;
}
const request = async (call: ApiRequest): Promise<ApiResponse> => {
try {
const options : any = {
url: call.url,
method: call.method,
params: call.params,
headers: {
'Content-Type': 'application/json',
...call.extraHeaders,
},
};
const response: HttpResponse = await makeCapacitorHttpCall(options);
console.log(response)
return {
data: response.data,
status: response.status,
headers: response.headers,
};
} catch (error: any) {
console.log(error)
throw {
data: error.response?.data,
status: error.response?.status,
headers: error.response?.headers,
};
}
};
const makeCapacitorHttpCall = async (options: any): Promise<HttpResponse> => {
switch (options.method) {
case 'GET':
return await CapacitorHttp.get(options);
case 'POST':
return await CapacitorHttp.post(options);
case 'PUT':
return await CapacitorHttp.put(options);
case 'PATCH':
return await CapacitorHttp.patch(options);
case 'DELETE':
return await CapacitorHttp.delete(options);
default:
throw new Error(`Unsupported HTTP method: ${options.method}`);
}
};
export default request;
I am calling in this place
export const geoposicionar = async (lat: string, lng: string) => {
try {
const response = await request({
url: 'https://maps.googleapis.com/maps/api/geocode/json',
method: 'GET',
// @ts-ignore
params: {
latlng: `${lat},${lng}`,
key: 'MyKey'
}
})
return response.data
} catch (error) {
console.error('Error al obtener información de la ubicación:', error);
}
};
and when I make the fetch i get this error
if I use axios, work all well, but when i use capacitor i have this problem.
It’s interesting that Axios
works. The CapacitorHttp
plugin’s web implementation uses fetch
. I would think they would both fail due to CORS if Google doesn’t allow that.
As an FYI, you don’t have to use the CapacitorHttp
plugin directly. You can use standard fetch
or XMLHttpRequest
(either by themselves or through Axios) and the Capacitor plugin will patch the requests through to the native libraries circumventing CORS all together. This patching is disabled by default. To enable, see the documentation .
Now obviously when testing in the web browser and not on an actual device (or emulator), you are always going to run into the CORS issue.
What does the Request look like when using Axios?
amav96
January 18, 2024, 9:34pm
3
Yes, i am using http capacitor for my app work in web and android. Http Capacitor work well when i request to my backend, but no with google, only axios
Wouldn’t it be a header problem? Which axios configures correctly and http capacitor does not?
this is my axios config
import axios, {
AxiosError,
AxiosRequestConfig,
AxiosResponse,
AxiosResponseHeaders,
ResponseType
} from 'axios';
import { Preferences } from '@capacitor/preferences';
export interface ApiRequest<T = any> {
url: string;
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
data?: T;
extraHeaders?: { [key: string]: string };
params?: URLSearchParams;
responseType?: ResponseType;
auth?: boolean
}
export interface ApiResponse<T = any> {
data: T;
status: number;
statusText: string;
headers: AxiosResponseHeaders;
}
const instance = axios.create({ baseURL: process.env.API_BASE_URL || 'http://localhost:10002/' });
const request = (call: ApiRequest): Promise<ApiResponse> => {
return new Promise(async (resolve, reject) => {
const onSuccess = (response: AxiosResponse) => {
resolve({
data: response.data,
status: response.status,
statusText: response.statusText,
headers: response.headers
});
};
const onError = (err: AxiosError) => {
console.log(err)
reject({
data: err.response?.data,
status: err.response?.status,
statusText: err.response?.statusText,
headers: err.response?.headers
});
};
const axiosCall: AxiosRequestConfig = {
url: call.url,
method: call.method,
data: call.data,
params: call.params as any,
responseType: call.responseType,
headers: {
'Content-Type': 'application/json',
...call.extraHeaders
}
};
if(call.auth){
let tokenAutenticado = await Preferences.get({ key: "_token" });
if (tokenAutenticado.value && axiosCall.headers) {
axiosCall.headers['Authorization'] = `Bearer ${tokenAutenticado.value}`;
}
}
instance(axiosCall).then(onSuccess).catch(onError);
});
};
export default request;


Looking at the error in more detail, it says the Content-Type
is invalid. Check the Axios request and see what Content-Type
that is sending.
amav96
January 18, 2024, 9:50pm
5
they are completly different the headers they sent
What matters is Content-Type
/ Accept
. Axios is everything vs. Capacitor is just JSON. Try setting responseType
to text
in HttpOptions
.
amav96
January 19, 2024, 12:01am
7
this worked
const options : any = {
url: call.url,
method: call.method,
data: call.data,
params: call.params,
headers: {
'Accept': 'application/json, text/plain, */*',
...call.extraHeaders,
},
responseType: 'text'
};
work with Accept option
But this new configuration hurt my other post requests hahaha. It should make it dynamic. But it’s not very practical, isn’t it?
Because with google api maps it works with accept, but when I go to my backend with post it doesn’t work?
so, work accep with get, and content-type with post. its right?
can it be a valid solution?
const options : any = {
url: call.url,
method: call.method,
data: call.data,
params: call.params,
headers: {
[call.method === 'GET' ? 'Accept' : 'Content-type']: 'application/json, text/plain, */*',
...call.extraHeaders,
},
};
Glad to hear it works with Accept
! That could work or try to make it more dynamic so it can be set on a case by case basis. Or can you just set both - Accept
and Content-Type
?
It seems though Accept
is usually used in a Request
and Content-Type
in the Response
(source ). Any reason your backend server doesn’t use Accept
?