为什么我得到一个跨域请求阻止:同源策略不允许读取远程资源

为什么我得到一个跨域请求阻止:同源策略不允许读取远程资源

问题描述:

好了,所以我玩弄使用的API,目前我使用的是GEONAMES API。我的问题是,它正常工作,直到......

Okay so I am playing around with using API's and currently I am using the geonames api. My problem is it works fine until...

让我来解释一下,当我写了code这样

Let me explain, when I write the code as such

$(document).ready(function() {


        Date.prototype.dateToString = function() {
               var yyyy = this.getFullYear().toString();
               var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based
               var dd  = this.getDate().toString();
               return yyyy + '-' + (mm[1]?mm:"0"+mm[0]) + '-' + (dd[1]?dd:"0"+dd[0]); // padding
        };

        var d = new Date();
        var date = d.dateToString();


        $.ajax({
            dataType: "json",
            url: url
        }).then(function(data){

            var latitude = data.geonames[0].lat;
            var longitude = data.geonames[0].lng;

            var north = parseFloat(latitude) + 1;
            var south = parseFloat(latitude) - 1;
            var east = parseFloat(longitude) + 1;
            var west = parseFloat(longitude) - 1;

            var uri = encodeURI("http://api.geonames.org/earthquakesJSON?north=" + north + "&south=" + south + "&east=" + east + "&west=" + west + "&date=" + date +"&username=demo"); 

            $.ajax({
                dataType: "json",
                url: uri
            }).then(function(eData){

                var myLatlng = new google.maps.LatLng(parseFloat(data.geonames[0].lat), parseFloat(data.geonames[0].lng));

                function initialize() {

                    var mapProp = {
                        center : myLatlng,
                        minzoom: 1,
                        maxzoom: 20,
                        zoom : 7,
                        mapTypeId : google.maps.MapTypeId.ROADMAP
                    };

                    var map = new google.maps.Map(document.getElementById("googleMap"),
                        mapProp);

                    var marker = new google.maps.Marker({
                        position: myLatlng,
                        map: map,
                        title: 'Search Location\nLatitude: ' + data.geonames[0].lat + '\nLongitude: ' + data.geonames[0].lng  
                    }); 

                    for(item = 0; item < eData.earthquakes.length; item++){

                        if (eData.earthquakes.length > 0){
                            var eLat = eData.earthquakes[item].lat, eLng = eData.earthquakes[item].lng;
                        } else {
                            var eLat = '', eLng = '';
                        }
                        new google.maps.Marker({
                            position: new google.maps.LatLng(eLat,eLng),
                            map: map,
                            title: 'Date and Time: '+eData.earthquakes[item].datetime+'\nMagnitude: '+eData.earthquakes[item].magnitude+'\nDepth: '+eData.earthquakes[item].depth+'\nLat: '+eData.earthquakes[item].lat+'\nLong: '+eData.earthquakes[item].lng 
                        });
                    }
                }
                initialize();

                });
            });
        });

这会工作得很好,加载网页时出现,因为它是应该做的,但是如果我把它包在这样的函数

It will work just fine, loads when the page comes up as it is supposed to do, However if I wrap it in a function like this

 function getSearch(url){
    $(document).ready(function() {


        Date.prototype.dateToString = function() {
               var yyyy = this.getFullYear().toString();
               var mm = (this.getMonth()+1).toString(); // getMonth() is zero-based
               var dd  = this.getDate().toString();
               return yyyy + '-' + (mm[1]?mm:"0"+mm[0]) + '-' + (dd[1]?dd:"0"+dd[0]); // padding
        };

        var d = new Date();
        var date = d.dateToString();


        $.ajax({
            dataType: "json",
            url: url
        }).then(function(data){

            var latitude = data.geonames[0].lat;
            var longitude = data.geonames[0].lng;

            var north = parseFloat(latitude) + 1;
            var south = parseFloat(latitude) - 1;
            var east = parseFloat(longitude) + 1;
            var west = parseFloat(longitude) - 1;

            var uri = encodeURI("http://api.geonames.org/earthquakesJSON?north=" + north + "&south=" + south + "&east=" + east + "&west=" + west + "&date=" + date +"&username=demo"); 

            $.ajax({
                dataType: "json",
                url: uri
            }).then(function(eData){

                var myLatlng = new google.maps.LatLng(parseFloat(data.geonames[0].lat), parseFloat(data.geonames[0].lng));

                function initialize() {

                    var mapProp = {
                        center : myLatlng,
                        minzoom: 1,
                        maxzoom: 20,
                        zoom : 7,
                        mapTypeId : google.maps.MapTypeId.ROADMAP
                    };

                    var map = new google.maps.Map(document.getElementById("googleMap"),
                        mapProp);

                    var marker = new google.maps.Marker({
                        position: myLatlng,
                        map: map,
                        title: 'Search Location\nLatitude: ' + data.geonames[0].lat + '\nLongitude: ' + data.geonames[0].lng  
                    }); 

                    for(item = 0; item < eData.earthquakes.length; item++){

                        if (eData.earthquakes.length > 0){
                            var eLat = eData.earthquakes[item].lat, eLng = eData.earthquakes[item].lng;
                        } else {
                            var eLat = '', eLng = '';
                        }
                        new google.maps.Marker({
                            position: new google.maps.LatLng(eLat,eLng),
                            map: map,
                            title: 'Date and Time: '+eData.earthquakes[item].datetime+'\nMagnitude: '+eData.earthquakes[item].magnitude+'\nDepth: '+eData.earthquakes[item].depth+'\nLat: '+eData.earthquakes[item].lat+'\nLong: '+eData.earthquakes[item].lng 
                        });
                    }
                }
                initialize();

                });
            });
        });
}

我得到这个错误....

I get this error....

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote 
resource at http://api.geonames.org/searchJSON?q=Fukushima&maxRows=10&username=demo. 
This can be fixed by moving the resource to the same domain or enabling CORS.

我还没有做足够的服务器端或正在与API的确切地知道这意味着什么,或者为什么会发生的唯一情况是,如果我试图调用从形式此方法。

I haven't done enough server side or working with API's to know exactly what this means, or why the only time it happens is if I am trying to call this method from a form.

::

虽然打字,我意识到,这不是包装的功能是这样做,而是当表单因此专家提到在错误的域名的URL的变化,我应该减慢至读好一点。然而,因为我做这在JavaScript和Ajax我想知道,因为我知道,表单处理,而不调用服务器如何,我会去这样做来完成。

While typing this I realized that it wasn't the wrapping in the function that was doing it but rather the changing of the URL when the form was submitted hence the mention of the domain in the error, I should have slowed down to read a little better. However since I am doing this in javascript and ajax I would like to know since I do know that form handling can be done without invoking the server how would I go about doing that.

我明白,如果没有人给出了一个直接的答案,我其实preFER,没有人做,而是指向我的客户端表单处理JavaScript和Ajax和简要说明其使用或历史文献的方向。

I understand if no one gives a direct answer I actually prefer that no one does but rather points me in the direction of documentation for client side form handling with javascript and ajax with a brief explanation or history of its use.

感谢大家!

CORS(跨域资源共享)规定,从浏览器发射的AJAX请求只能与他们相同的主机。这意味着,使用上的JavaScript disney.com运行只能使AJAX请求到其他disney.com端点。

CORS (cross-origin resource sharing) stipulates that AJAX requests fired from a browser can only contact their same host. This means that JavaScript running on disney.com can only make AJAX requests to other disney.com endpoints.

您的问题是,你发送请求到api.geonames.org即使你很可能您自己的主机,而不是api.geonames.org网站上运行。

服务器可以启用CORS,这意味着它们将接受来自其他域的请求。但是,每个服务器都是不同的,大多数API仍然不允许跨域请求。它看起来像api.geonames.org是这些不支持CORS 1

Servers can enable CORS, meaning that they will accept requests from other domains. However, each server is different and most APIs still do not allow cross-origin requests. It looks like api.geonames.org is one of these that does not support CORS.

需要注意的是CORS只适用于从浏览器发送的请求。击中该API从后端服务器(如Node或Rails的)会工作得很好。

Note that CORS only applies to requests sent from a browser. Hitting that API from a backend server (like Node or Rails) will work just fine.