2012-09-03 15 views
6

Proszę rozważyć ten skrypt:Otrzymuj .csv plik jako dane w funkcji sukcesu ajax

$.ajax({ 
    url:'http://ichart.finance.yahoo.com/table.csv?s=GS&a=00&b=1&c=2010&d=08&e=3&f=2012&g=d&ignore=.csv', 
    type:'get', 
    dataType:'jsonp', 
    success:function(data){ 
     alert(data); 
    } 
}) 

URL zwraca plik .csv, ale jestem z określeniem rodzaju jsonp danych, ponieważ jest to żądanie ajax cross-domain . Bez tego parametru pojawia się błąd "pochodzenia nie jest dozwolony".

Ponieważ określam typ danych jsonp, funkcja ajax generuje błąd, ponieważ plik .csv nie ma formatu JSON. Ale w konsoli programisty widzę, że przeglądarka otrzymuje spójny plik .csv. Tak więc wiem, że pomyślnie otrzymuję plik CSV. Myślę, że powinno to być możliwe, ale nie jestem pewien, jak poprawnie otrzymać ten plik csv do mojej funkcji ajax?

Oczywiście, jeśli mógłbym zrobić ten URL, zwrócę poprawnie sformatowany ciąg JSON, który byłby najlepszy, ale nie jestem pewien, czy mogę to zrobić.

Oto skrzypce, gdzie można spróbować, trzeba będzie otworzyć konsolę dev zobaczyć ten błąd: http://jsfiddle.net/92uJ4/3/

Każda pomoc jest mile widziana.

Tim

Odpowiedz

7

Niestety, ograniczenia cross-domain oznacza, że ​​to po prostu nie będzie działać. System jest zbudowany specjalnie po to, aby nie można było pobrać arbitralnej zawartości między domenami za pomocą AJAX. Nie istnieje żadna metoda wstępnego przetworzenia danych innych niż JSONP na rzeczywiste dane JSONP (ponieważ to pokonałoby punkt ograniczeń).

Będziesz musiał albo wykonać połączenie z lokalnym serwerem, który ściąga dane z Yahoo! i wysyła go na twoje żądanie AJAX lub znajduje jakąś usługę, która pobierze z dowolnego adresu URL i zwróci dane jako JSONP. Tak się składa, że ​​Yahoo! zapewnia właśnie taką usługę: YQL (język zapytań Yahoo). Aby uzyskać więcej informacji, patrz this link.

Aby osiągnąć to, czego chce, użyć kodu w tym skrzypce: http://jsfiddle.net/c5TeM/1/

function get_url(remote_url) { 
    $.ajax({ 
     url: "http://query.yahooapis.com/v1/public/yql?"+ 
"q=select%20*%20from%20html%20where%20url%3D%22"+ 
encodeURIComponent(remote_url)+ 
"%22&format=json", 
     type: 'get', 
     dataType: 'jsonp', 
     success: function(data) { 
      alert(data.query.results.body.p); 
     }, 
     error: function(jqXHR, textStatus, errorThrow){ 
      alert(jqXHR['responseText']); 
     } 
    }) 
} 
+0

Dziękuję za wspaniałą informację. Myślałem, że tak naprawdę ta metoda pozyskiwania informacji nie była możliwa. Twoje rozwiązanie wygląda świetnie, patrzyłem na YQL wcześniej, myślę, że to jest sposób, aby to zrobić. –

+0

Czy ta implementacja zapisuje cokolwiek w bazie danych YQL? lub czy po prostu pobiera dane do dalszej manipulacji? Dzięki @JoeC –

+0

@PT_C: O ile mi wiadomo, nie zapisuje niczego w bazie danych YQL. To powinno być po prostu przejście. Jednakże, ponieważ jest to strona trzecia, nie można zagwarantować, że nie logują informacji przechodzących przez ich systemy, więc nie użyłbym tego dla niczego wrażliwego. Lepiej byłoby zaimplementować własne rozwiązanie po stronie serwera do wyciągania danych w takim przypadku. –

0

Modyfikowanie ostatnim warunkiem jsfiddle doprowadzić mnie do następującego rozwiązania:
http://jsfiddle.net/9zcsxq5a/

var str_parse = function(data){ 
    data = data.replace(/<[/]*body[^>]*>/g,''); 
    data = data.replace(/<--[\S\s]*?-->/g,''); 
    data = data.replace(/[\r]+/g,''); 
    data = data.replace(/<noscript[^>]*>[\S\s]*?<\/noscript>/g,''); 
    data = data.replace(/<script[^>]*>[\S\s]*?<\/script>/g,''); 
    data = data.replace(/<script.*\/>/,''); 
    return data 
} 

get_url = function(URL){ 
    $.ajax({ 
    url:"http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22"+ 
    encodeURIComponent(URL)+"%22", 
    dataType: "jsonp", 
    type: 'get', 
    success: function(r){ 
     data=r.results[0]; 
     data = str_parse(data); 
     data = data.split(/[\n]+/); 

    //// first line of the csv holds the colnames 
     var HEADER = data[0].split(","); 
     data.shift(); 

    /// create { OBJECT } structure for each row 
     data = (function(){ 
     var o=[]; 
     data.forEach(function(E){ 
      o.push((function(){ 
      var _o={}; 
      for(var i=0, s=E.split(",");i<s.length;i++) 
       _o[HEADER[i]]=s[i]; 
      return _o; 
      }())); 
     }); 
     return o; 
     }()); 

    /// THE FINAL OBJECT 
     console.log(data); 
     return data; 
    } 
    }); 
} 

$('#a').click(function() { 
    get_url("http://ichart.finance.yahoo.com/table.csv?a=8&b=11&e=10&g=d&c=2005&d=2&f=2016&s=YHOO"); 
}); 


The csv is passed through, asis and will then be modified to become a json object, similar to the one (but whithout date restrictions) that you will, get when you use

http://query.yahooapis.com/v1/public/yql?q=select%20%2a%20from%20yahoo.finance.historicaldata%20where%20symbol%20in%20%28%27YHOO%27%29%20and%20startDate%20=%20%272009-09-11%27%20and%20endDate%20=%20%272010-03-10%27&diagnostics=true&env=store://datatables.org/alltableswithkeys