I have a simple call out to google API from a javascript webresource in Dynamics CRM 365.
var xhr = new XMLHttpRequest();
xhr.open("GET", 'https://maps.googleapis.com/maps/api/place/queryautocomplete/json?input={' + searchString + '}&types=address&language=en&crossDomain=true&key=[ourKey]', true);
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
xhr.setRequestHeader('Access-Control-Allow-Methods', 'GET,POST');
xhr.onload = function () {
var response = JSON.parse(xhr.responseText);
//do something with the response here
};
xhr.send();
I get the following messages and errors in dev tools in IE:
*SEC7118: XMLHttpRequest for https://maps.googleapis.com/maps/api/place/queryautocomplete/json?input={55 lllll}&types=address&language=en&crossDomain=true&key=[ourKey] required Cross Origin Resource Sharing (CORS). File: ClientApiWrapper.aspx
SEC7119: XMLHttpRequest for https://maps.googleapis.com/maps/api/place/queryautocomplete/json?input={55 lllll}&types=address&language=en&crossDomain=true&key=[ourKey] required CORS preflight. File: ClientApiWrapper.aspx
SEC7120: Origin http://[ourURL] not found in Access-Control-Allow-Origin header. File: ClientApiWrapper.aspx
SCRIPT7002: XMLHttpRequest: Network Error 0x80070005, Access is denied. File: ClientApiWrapper.aspx*
Looking through CORS related material and guides, I believe I've done everything right.
I've also tried this, albeit I expect a CORS issue here:
jQuery.post('https://maps.googleapis.com/maps/api/place/queryautocomplete/json?input={' + searchString + '}&types=address&language=' + langCode + '&key=[ourKey]', function (addresses) {
try {
//Do something with returned addresses here...
}
catch (e) {
alert("AutoComplete ErrorInt: " + e.message);
}
});
I'm sure this is a Dynamics CRM related issue where dynamics doesn't play nicely outside it's own sandbox.
Can anyone please suggest a fix within the Dynamics CRM realm?
Thanks
The Access-Control-Allow-Origin
and Access-Control-Allow-Methods
headers are response headers, which are sent from the server in response to your request.
Just remove them completely from your xhr request code. The browser will add the Origin
header for you (you do not specify it explicitly), and the server at maps.googleapis.com
should add the required CORS response headers (Access-Control-Allow-Origin
and possibly some others).
If you're still getting problems after that, post a full set of request and response headers for the GET request (and for the preflight OPTIONS request if there is one).
EDITED FOLLOWING COMMENTS
OK, so here's what I see from your comments (formatted):
var xhr = new XMLHttpRequest();
xhr.open("GET", 'maps.googleapis.com/maps/api/place/queryautocomplete/…{' +
searchString + '}&types=address&language=en&crossDomain=true&key=[ourKey]',
true);
xhr.onload = function () {
var response = JSON.parse(xhr.responseText);
//do something with the response
};
xhr.send();
Errors: SEC7120: Origin http://[ourUrl] not found in Access-Control-Allow-Origin header. File: ClientApiWrapper.aspx
GET /maps/api/place/queryautocomplete/json?input={55%20saddl}&types=address&language=en&crossDomain=true&key=[ourKey] HTTP/1.1
Accept: /
Referer: http://[ourURL]/[ourOrg]/form/ClientApiWrapper.aspx?ver=1166920881
Accept-Language: en-CA
Origin: http://[ourURL]
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Host: maps.googleapis.com
Connection: Keep-Alive
Cache-Control: no-cache
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Date: Wed, 25 Apr 2018 16:26:36 GMT
Expires: Wed, 25 Apr 2018 16:31:36 GMT
Cache-Control: public, max-age=300
Server: scaffolding on HTTPServer2
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
OK, so the browser is sending the Origin header. That means that your server needs to return some CORS response headers.
So you need to add code at the server to return the following CORS response header for OPTIONS, GET and POST requests:
Access-Control-Allow-Origin: <value of Origin request header>
(what I mean by that is that the server should extract the value of the Origin request header (i.e. http://[ourURL]
) and return that as the value of the Access-Control-Allow-Origin
response header. Don't hardcode it as 'http://[ourURL]
' - that way lies madness!).
You will also need to return the following additional CORS headers for OPTIONS requests only:
Access-Control-Allow-Methods: <value-of-Access-Control-Request-Method request header>
Access-Control-Allow-Headers: <value-of-Access-Control-Request-Headers request header>
Access-Control-Max-Age: 86400
That last one specifies the number of seconds that the browser should cache the preflight OPTIONS response, so it doesn't need to get made each time. It is optional, but advised. 86400 seconds = 1 day.
That should get you going.
So, after all that messing around, I posted an issue on Google API dev support. Here's what came back...hope it helps other's trying something similar:
Thank you for posting. I can see that you are using Places API Web Service in your HTTP request. Places API web service is not intended to be used on client-side applications as responses don’t contain the Access-Control-Allow-Origin header. See more in the duplicate issue. To use Places API in a JS application, I suggest you use the Places Library in Maps Javascript API 1. This library offers an autocomplete2 feature that you can find in Places API web service. If you want the queryautocomplete feature of the web service, Javascript API provides getQueryPredictions() function as stated in the documentation 3.
User contributions licensed under CC BY-SA 3.0