So I need ASAP to do a request to the Google Places API using Dart for a flutter web app. I am using Dio I found some answers, which said that XMLHttpRequest Error would disappear if I added headers. I added the headers and the problem persists. I received some help from a Software Engineer (I'm a newbie), and although he was unfamiliar with Dio, he edited a file in the flutter SDK which disabled security with the flag --disable---web-security
path: C:\flutter\packages\flutter_tools\lib\src\web file: chrome.dart
(Here I only added the code block changed from the file)
final int port = debugPort ?? await _operatingSystemUtils.findFreePort();
final List<String> args = <String>[
chromeExecutable,
// Using a tmp directory ensures that a new instance of chrome launches
// allowing for the remote debug port to be enabled.
'--user-data-dir=${userDataDir.path}',
'--remote-debugging-port=$port',
// When the DevTools has focus we don't want to slow down the application.
'--disable-background-timer-throttling',
// Since we are using a temp profile, disable features that slow the
// Chrome launch.
'--disable-extensions',
'--disable-popup-blocking',
'--bwsi',
'--no-first-run',
'--no-default-browser-check',
'--disable-default-apps',
'--disable-translate',
'--disable-web-security', //the line added
if (headless) ...<String>[
'--headless',
'--disable-gpu',
'--no-sandbox',
'--window-size=2400,1800',
],
url,
];
Once web security was disabled, Dio worked fine, with the API. The request is executed and returns with a 200 according to the DevTools console but then security blocks it off. So my question is what header am I missing, or what should I add to the Dio() object in order to re-activate web security and be able to make requests.
Dio request to Places API
try {
var dio = Dio();
dio.options.headers["Access-Control-Allow-Credentials"] = "true";
dio.options.headers["Access-Control-Allow-Headers"] =
"Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,locale";
dio.options.headers["Access-Control-Allow-Origin"] = "*";
dio.options.headers["Access-Control-Allow-Methods"] =
"GET, HEAD, POST, OPTIONS";
dio.options.responseType = ResponseType.json;
String url =
autocompleteUrl(search, sessionToken, locale, components, placeType);
//print(url);
var response = await dio.get(url);
var json = convert.jsonDecode(response.data);
var jsonResults = json[_f.predictions] as List;
return jsonResults.map((p) => PlaceSearch.fromMap(p)).toList(); //modeling the response
} on DioError catch (e) {
return null;
}
Thank you for taking the time to help.
EDIT:
When I would print the error data this would show up
request : null
message : XMLHttpRequest error.
DioError [DioErrorType.RESPONSE]: XMLHttpRequest error.Error in DevTools:
Access to XMLHttpRequest at 'https://maps.googleapis.com/maps/api/place/autocomplete/json?input=a&key=keyg&sessionToken=e1f7496d-a62e-437d-877d-d93e5045e22d&language=null&components=country:us&types=address' from origin 'http://localhost:49234' 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.
The same-origin policy causing the error only happens when the request is from client to server not from server to server. So I created a cloud function that makes the request and returns the response. Below is the function in typescript
import axios from "axios";
export const serverRequest = functions.https.onCall(async (url, context)=> {
isAuthenticatedAdmin(context);
const response = await axios.get(url as string).then(({data})=> data);
return response;
});