我正在尝试使用Bootstrap 3's Typeahead script自动填充机场查询。
这是我尝试使用的网络服务: http://airportcode.riobard.com/about#about
我修改了另一个工作的jsfiddle(原始工作源和数组键已注释掉并替换为新的)
// instantiate the bloodhound suggestion engine
var airports = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
//url: 'http://api.themoviedb.org/3/search/movie?query=%QUERY&api_key=470fd2ec8853e25d2f8d86f685d2270e',
url: 'http://airportcode.riobard.com/search?q=%QUERY&fmt=JSON',
filter: function (airports) {
return $.map(airports.results, function (airport) {
return {
//value: airport.title
value: airport.name
};
});
}
}
});
// initialize the bloodhound suggestion engine
airports.initialize();
// instantiate the typeahead UI
$('.typeahead').typeahead(null, {
name: 'airports',
displayKey: 'value',
source: airports.ttAdapter()
});
http://jsfiddle.net/UkB7u/109/
不确定为什么它不起作用,据我所知,它应该按原样运行,但事实并非如此。
答案 0 :(得分:3)
它无法正常工作的原因是same-origin policy,这是当今所有主流浏览器实施的安全策略,阻止浏览器向托管在其上的服务发出请求不同的领域。您可以通过查看Web浏览器的控制台来判断这种情况。我在尝试从您的示例小提琴中搜索机场代码时,在Chrome的开发人员工具中看到此错误:
XMLHttpRequest cannot load http://airportcode.riobard.com/search?q=ORD&fmt=JSON. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.
请注意,原始域名为fiddle.jshell.net
,而您尝试访问的服务位于airportcode.riobard.com
域。由于同源策略,您无法在不跳过某些环节的情况下向另一方发出请求。
为了更深入地解释为什么同源政策首先存在以及它为何如此重要,请参阅答案:
https://security.stackexchange.com/questions/8264/why-is-the-same-origin-policy-so-important
关于如何绕过同一原产地政策的一些想法,请阅读:
Ways to circumvent the same-origin policy
我可以说,如果没有airportcode.riobard.com
的某种合作,CORS就无法运行(它要求服务器的响应包含特定的HTTP标头Access-Control-Allow-Origin
)。 JSONP或基于iframe的方法可以工作,但两者都有点hacky,IMO。
你可以解决这个问题的最简单方法是创建一个"代理"在你自己的服务器上。也就是说,您不是通过JavaScript代码与此外部服务进行通信,而是通过HTTP调用自己的服务器并让它从远程服务器获取数据。这是有效的,因为在您的Web服务器上运行的代码不受同源策略限制 - 只有客户端代码。