Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flutter Web AutocompletePlace XMLHttpRequest Error #14

Open
Bylinkk opened this issue May 9, 2023 · 17 comments
Open

Flutter Web AutocompletePlace XMLHttpRequest Error #14

Bylinkk opened this issue May 9, 2023 · 17 comments

Comments

@Bylinkk
Copy link

Bylinkk commented May 9, 2023

Hi,

After reading multiple XMLHttpRequest errors and CORS security issues, I can't work the autocomplete search on Chrome. Can we just remove this function to give the user the possibility to only use the current location button? Or can you help me to make this function work easily ?
Thank you in advance for your return.

@rvndsngwn
Copy link
Member

Hi @Bylinkk I will update it as soon as possible. Could you please elaborate on your problem?

@rvndsngwn
Copy link
Member

Hey @Bylinkk , this is caused by CORS.

@Bylinkk
Copy link
Author

Bylinkk commented May 13, 2023

Thanks for your feedback.
Indeed the problem is caused by CORS. When I try to use a proxy, it doesn't work.
I use the geoCodingBaseUrl parameter with this value :
geoCodingBaseUrl: "https://api.allorigins.win/raw?url=https://maps.googleapis.com/maps/api/geocode/json/",
I also tried this :
geoCodingApiHeaders: const { "Access-Control-Allow-Origin":'*', "Access-Control-Allow-Methods": 'GET', },
concerning disabled security, it works well on my side but the user will not do it on his side !

I really don't know how to solve this problem!

@rvndsngwn
Copy link
Member

rvndsngwn commented May 13, 2023

It seems to be only a problem with localhost, after the deployment CORS problems are automatically fixed. You can try it once 🤔 I'm not sure.

@Bylinkk
Copy link
Author

Bylinkk commented May 16, 2023

Hi,

I just did the test in production but the CORS problem is still present. You can check for yourself on the following links:
Pre production web site
Then click on "Menu | Commande WhatsApp" then on the profile icon of the bottom app bar then "Ajouter votre adresse de livraison".

The javascript console displays the CORS error:

/#/:1 Access to XMLHttpRequest at 'https://maps.googleapis.com/maps/api/geocode/json/geocode/json?latlng=0.0017568469044719824%2C-0.002709031105041504&key=API_KEY' from origin 'https://dev2.scan.feadys.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Failed to load resource: net::ERR_FAILED

Google Maps JavaScript API has been loaded directly without a callback. This is not supported and can lead to race conditions and suboptimal performance. For supported loading patterns please see https://goo.gle/js-api-loading

Thank you for your help

@jansvanda
Copy link

hi @rvndsngwn I am experiencing the same issue, tried already many things like adding the headers
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods":
"GET, POST, OPTIONS",
"Access-Control-Allow-Headers":
"X-Requested-With, Content-Type, Origin, Accept, token"

Also tried some CORS proxies, but those are just temporary solutions.

Still getting "has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.".

Tried to make server side changes, nothing helps. I don't know what to do anymore. My app works on mobile but not on web. Sadly

@rvndsngwn
Copy link
Member

rvndsngwn commented Jun 14, 2023

https://pub.dev/packages/flutter_cors

Guys you can use this package only for local testing.

@rvndsngwn
Copy link
Member

@Bylinkk Bylinkk closed this as completed Jun 15, 2023
@Bylinkk Bylinkk reopened this Jun 15, 2023
@Bylinkk
Copy link
Author

Bylinkk commented Jun 15, 2023

Hi @rvndsngwn
I will test this. Thank you very much for your come back

@thisisprabhat
Copy link

I have worked on it, the same issue was with me, so I used OpenStreetMap instead and got the desired result.

@AndresPinto2203
Copy link

This problem has been presented to me in several opportunities when I try to use google apis (youtube, address, places, etc) from flutter web, the way in which I have solved it is defining functions in my services api rest that make of pass buckets to make the requests to google and to return the answers to my application, in the case of the widget PlacesAutocomplete has the property placesBaseUrl, there you define your route in the backend where you consult the services of google, in my case it is: https://my.api.server.com/utils.

But the routes that I define in my server to consume the google services were:

https://my.api.server.com/utils/place/autocomplete/json?input=address exampl

for this service I use the function:

async getPlacesByInput(input: string): Promise {
try {
let response = await axios.get(https://maps.googleapis.com/maps/api/place/autocomplete/json?input=${input}&key=${GOOGLE_API_KEY});
if (response.status == 200) {
return response.data;
}
} catch (error) {
console.error('error', error);
return {};
}
}

https://my.api.server.com/utils/place/details/json?placeid=placeIdExample

and for this service I use the function:

async getPlaceDetails(placeId: string, returnAll: Boolean): Promise {
try {
let response = await axios.get(https://maps.googleapis.com/maps/api/place/details/json?place_id=${placeId}&key=${GOOGLE_API_KEY});
if (returnAll) {
return response.data;
}
if (response.status == 200) {
return {
placeDetails: JSON.stringify(response.data.result),
stateName: response.data.result.address_components.find((component: any) => component.types.includes('administrative_area_level_1'))?.long_name,
};
} else {
console.error(response.data);
return '';
}
} catch (error) {
console.error('error', error);
return '';
}

}

I hope my explanation helps you. Happy code!!!!

@AnandSaran
Copy link

How to fix this CORS issue, Any update ?

@zahidshaikh08
Copy link

Any updates on this?? As for me it works fine on any pc's web browser but does not work from any mobile browser.

@bertrandgelinas
Copy link

bertrandgelinas commented Sep 4, 2024

For Geocoding

You need to build a proxy on your server in order to be able to get your correct response. The actual service is always returning CORS issues so building your own make you control the access control.

On Flutter

GoogleMapLocationPicker(
              mapType: MapType.normal,
              geoCodingBaseUrl:
                  "Your REST (GET) API", // You need to add your API HERE
              geoCodingApiHeaders: {
                'Content-Type': 'application/json',
                'Accept': 'application/json',
              },
              searchHintText: tr(LocaleKeys.choose_location),
              apiKey: firebase.app.options.apiKey,
              currentLatLng:
                  LatLng(currentPosition.latitude, currentPosition.longitude),
              onPlacesDetailsResponse: (pick) => onPlacePicked(pick!.result),
              onNext: (pick) => onPlacePicked(pick!),
              language: "fr",
              region: "ca",
            )

I built that quick NodeJS firebase function that mimic the same URL of geocoding (in that case) :

recalculateApi.get("/geocode/json?", async (req, res) => {  // Here make sure you use the exact "/geocode/json?" to make sure it fits the actual flutter call
  const latlng = req.query.latlng as string;
  const language = req.query.language as string;
  const key = req.query.key as string;

  if (!latlng || !language || !key) {
    res.status(400).send('Missing required query parameters: latlng, language, key');
    return;
  }

  try {
    const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latlng}&language=${language}&key=${key}`;
    console.log(`Calling ${url}`);
    const apiResponse = await axios.get(url);

    res.status(200).send(apiResponse.data);
  } catch (error: any) {
    res.status(500).send(`Error calling Google Maps API: ${error.message}`);
  }
});

Then it works fine. That still a lot of work for something that could already work....

@rvndsngwn
Copy link
Member

To resolve the CORS issue, easiest way is use Firebase function or Appwrite cloud function. Both are have freemium plans.

Thank you, @bertrandgelinas , for providing the best guidance on how to use firebase functions.

Firebase: https://firebase.google.com/docs/functions
Appwrite: https://appwrite.io/docs/products/functions/functions

https://github.com/appwrite/templates/tree/main/dart

@Bylinkk
Copy link
Author

Bylinkk commented Sep 21, 2024

The function of @bertrandgelinas concerns geocoding. For place search use this instead:

On flutter
placesBaseUrl: "<REST API>/placesProxy", placesApiHeaders: const { 'Content-Type': 'application/json', 'Accept': 'application/json', },

On firebase function

`// Fonction Firebase pour proxy l'API Google Places
exports.placesProxy = functions.https.onRequest(async (req, res) => {
  // Ajouter l'en-tête CORS pour permettre l'accès depuis n'importe quel domaine (localhost)
  res.set("Access-Control-Allow-Origin", "*");
  res.set("Access-Control-Allow-Methods", "GET, POST");
  res.set("Access-Control-Allow-Headers", "Content-Type, Authorization");

  // Gérer les requêtes OPTIONS pour CORS
  if (req.method === "OPTIONS") {
    res.status(204).send("");
    return;
  }

  const input = req.query.input;
  const language = req.query.language;
  const key = req.query.key;

  if (!input || !language || !key) {
    res.status(400).send("Missing required parameters: input, language, key");
    return;
  }

  try {
    // URL de l'API Google Places pour l'autocomplétion
    const url = `https://maps.googleapis.com/maps/api/place/autocomplete/json?input=${input}&language=${language}&key=${key}`;

    console.log(`Calling ${url}`);

    // Appel à l'API Google Places via Axios
    const apiResponse = await axios.get(url);

    // Réponse avec les données de l'API
    res.status(200).send(apiResponse.data);
  } catch (error) {
    res.status(500).send(`Error calling Google Places API: ${error.message}`);
  }
});`

However, the search works well but there is an error when selecting the chosen address:

#0 packages/map_location_picker/src/autocomplete_view.dart 504:7 _getDetailsByPlaceId
├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
│ ⛔ FormatException: SyntaxError: Unexpected token 'M', "Missing re"... is not valid JSON

I wrote my message too quickly

@Bylinkk
Copy link
Author

Bylinkk commented Sep 21, 2024

@AndresPinto2203 Where do you call this function: getPlaceDetails ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants