Load Google Maps asynchronously with AWS Cloud Center

My google map is loaded asynchronously only after page reload or HTTP redirect. For the first onload, it won't show up - none of the javascript is called.

In Rails development mode, it works without any problem. Likewise, the map is loaded asynchronously in production mode if I serve the assets locally. But when I setup CDN Cloud Cloud of Amazon Web Services it fails on first page load.

Here's the javascript from the view that calls the map:

  <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.10.1.min.js"></script>


  <script type="text/javascript">

function initialize() {

var map = new google.maps.Map(document.getElementById('map'), {
  zoom: 4,
  streetViewControl: false,
  overviewMapControl: false,
  mapTypeControl: false,
  zoomControlOptions: {
    style: google.maps.ZoomControlStyle.DEFAULT,
  },
  center: new google.maps.LatLng(39.82, -98.58),
});


// Info Window Content
var infoWindowContent = <%= raw @content %>;
var locations = <%= raw @location %>;

 // Display multiple markers on a map

var infowindow = new google.maps.InfoWindow(), marker, i;

var marker, i;
var markers = new Array();

for (i = 0; i < locations.length; i++) {  
  marker = new google.maps.Marker({
    position: new google.maps.LatLng(locations[i][1], locations[i][2]),
    map: map
  });

  markers.push(marker);

  google.maps.event.addListener(marker, 'click', (function(marker, i) {
    return function() {
      infowindow.setContent(infoWindowContent[i][0]);
      infowindow.open(map, marker);
    }
  })(marker, i));
}

}
   function loadScript() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&' +
    'callback=initialize';
document.body.appendChild(script);
  }

    window.onload =loadScript;
     </script>  

      

Any idea what could be wrong with the code on AWS Cloudfront?

+3


source to share


1 answer


Wow. Finally solved it.

Several things went wrong.

First, AWS S3 and Cloudfront do not allow CORS or cross-sourcing by default. This means that you cannot call an AJAX resource served either - it won't work. However, you can configure both options to allow CORS. To do this, you need to edit the S3 statement permissions and add CORS configuration (AWS offers good examples on the help pages). Next, you need to whitelist the "Origin" header to your Cloudfront distribution. This will allow the cloud front to forward the Origin header from the response request and enable CORS. (I didn't fully understand that this would work). Check AWS CORS Help Resources for more information)

Second, I noticed that although my AJAX script was being served locally and not Cloudfront, the other javascript file was: my Turbolinks js file . It turns out that the Turbolinks gem that the Rails Asset Pipeline requires creates a js file that was downloaded to my distribution (it is required by default in the application.js file). If you read the Turbolinks documentation you will see that Turbolinks only guarantees reloading of the body and html header. This is from the README:

 "Instead of letting the browser recompile the JavaScript and CSS between each page
  change, it keeps the current page instance alive and replaces only the body and 
  the title in the head"

      

As it turned out, Turbolinks was interfering with local AJAX and was preventing Google Map from loading asynchronously. Since the AWS CORS config dodged me, I just added the option to disable turbolinks for the link leading to the Google Maps page:



data: { no_turbolink: true }

      

to make a full link:

<%=link_to "/map", data: { no_turbolink: true } %>

      

Without turboprop, the page was never called using the Cloudfront Turbolinks.js file and so the local AJax could load the google map.

Hope this helps you tired travelers!

+3


source







All Articles