Andy Andy - 1 year ago 122
Javascript Question

Bootstrap Typeahead with Airport IATA codes

I'm trying to use Bootstrap 3's Typeahead script to auto populate an airport lookup.

This is the web service I am trying to use:

I've modified another working jsfiddle (original working source and array key commented out and replaced with new ones)

// instantiate the bloodhound suggestion engine
var airports = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
//url: '',
url: '',
filter: function (airports) {
return $.map(airports.results, function (airport) {
return {
//value: airport.title

// initialize the bloodhound suggestion engine

// instantiate the typeahead UI
$('.typeahead').typeahead(null, {
name: 'airports',
displayKey: 'value',
source: airports.ttAdapter()

Not sure why it's not working, as far as I can tell it should work as is but it doesn't.

Answer Source

The reason it's not working is because of the same-origin policy, a security policy that is implemented by all major browsers today which prevents the browser from being able to make requests to services that are hosted on a different domain. The way you can tell this is the case is by looking in your web browser's console. I'm seeing this error in Chrome's developer tools when trying to search for an airport code from your example fiddle:

XMLHttpRequest cannot load No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '' is therefore not allowed access. 

Note that the originating domain is, while the service you're trying to access is on the domain. Due to the same-origin policy, you won't be able to make requests from one to the other without jumping through some hoops.

For a more in-depth explanation of why the same-origin policy exists in the first place and why it's so important, see the answer here:

For some ideas on how you can circumvent the same origin policy, read here:

Ways to circumvent the same-origin policy

I can say that CORS isn't going to work without some cooperation from (it requires the server's response to include a specific HTTP header, Access-Control-Allow-Origin). JSONP or an iframe-based method could work, but both are kind of hacky, IMO.

The simplest way you could get around this is to create a "proxy" on your own server. That is, rather than communicating with this external service from your JavaScript code, you instead make HTTP calls to your own server and have it go fetch the data from the remote server. This works because the code running on your web server is not subject to the same-origin policy restrictions - only the client-side code is.