Заблокированы запросы между источниками: несколько API; нужно агрегировать данные

Задача: получить precipIntensity на несколько дней как минимум из 3 API. Основная проблема: заблокирован запрос между источниками, что приводит к тому, что данные не определены. Что такое запрос между источниками и как я могу решить эту проблему, которая мешает оператору If() и сбору собранных данных JSON в агрегаты для среднего значения? Обновленное решение:

    //Get the back dated times and current in UNIX, 
   //later make a lookup that gives datediff from current date and user's date and adjust index i condition to equal exact days.
            var totalPrecipSinceDate;
            var threeDayAPITimes = [];

        for (var i = 0; i <= 2; i++) //place user userData-1 where i <= input
    {
        var myDate = new Date(); //http://stackoverflow.com/questions/7693170/javascript-convert-from-epoch-string-to-date-object
        var epoch = myDate.getTime(); 
        var unixEpoch = Math.round(epoch/1000)
        threeDayAPITimes[i] = Math.round(unixEpoch - (86400 * i));

    }
    //Plan to convert UNIX dates to display

    //List of locations: LATITUDE,LONGITUDE
    var locations = ["46.3494,-85.5083"]

    //setup a server-side proxy which would hide the API key from the client side
    var currentAPIKey ="privateKey"; //gets an APIkey from user input.



var listAPIs = "";

$.each(threeDayAPITimes, function(i, time) {
    var darkForecastAPI= "https://api.forecast.io/forecast/" + currentAPIKey + "/" + locations + "," + time +"?callback=?"; 
     $.getJSON(darkForecastAPI, {
        tags: "WxAPI[" + i + "]",  //Is this tag the name of each JSON page? I tried to index it incase this is how to refer to the JSON formatted code from the APIs.
        tagmode: "any",
        format: "json"
    }, function(result) {
        // Process the result object    
        var eachPrecipSum = 0;
    if(result.currently.precipIntensity >=0 && result.currently.precipType == "rain")
        {
            $.each(result, function() {
              eachPrecipSum += (this.currently.precipIntensity);
              totalPrecipSinceDate += eachPrecipSum ;  ///Write mean precip
                        alert(eachPrecipSum );
        });

    }   
});
});

введите здесь описание изображения

введите здесь описание изображения


person safron6    schedule 02.05.2015    source источник
comment
у вас есть доступ к конфигурации вашего веб-сервера? Если это так, исправить это очень просто. Если нет, то вам придется использовать серверный язык.   -  person    schedule 02.05.2015


Ответы (4)


Запрос Cross-Origin — это когда вы делаете запрос к другому домену. Для защиты пользователя это запрещено по умолчанию. Браузеры работают по одной и той же политике происхождения. Это означает, что вы можете делать запросы только в одном и том же домене.

Вы не можете решить проблему запроса на перекрестное происхождение. Владелец прогноза. Io должен будет авторизовать ваш домен с помощью заголовка HTTP. Я предполагаю, что они не собираются этого делать. По сути, CORS дает контроль источника над тем, кто может использовать API, а не потребителем.

Лучше всего, скорее всего, обойти это ограничение. Вам нужно будет использовать JSONP. Они поддерживают это, но отмечают очень мудрое предостережение в своей документации: Возвращайте ответ API как JSONP. Пожалуйста, соблюдайте осторожность при его использовании, так как публичное раскрытие вашего ключа API представляет собой угрозу безопасности и, в случае злоупотребления, приведет к отзыву вашего ключа API. Тем не менее, если вы разрабатываете приложение для личного или внутреннего использования, это удобный способ сделать это.

Чтобы включить JSONP, просто введите ?callback=? В качестве строки запроса вашего URL. Это заставит jQuery настроить JSONP. В вашем примере вы будете делать это в любом месте, где вы создаете URL-адрес, поэтому здесь:

var darkForecastAPI= "https://api.forecast.io/forecast/" + currentAPIKey + "/" + locations + "," + time +"?callback=?";

Однако, как они упоминают, ваш ключ API открыт, поэтому будьте осторожны. Если возможно, создайте серверную веб-службу на своем сервере, которая действует как прокси между вашим JavaScript и их API. Не уверен, что это возможно, но на их сайте они предоставляют один, написанный на PHP, и вы можете довольно легко написать его на любом языке.

Позвольте мне также рассказать вам немного о JSONP, так как вы, вероятно, впервые слышите об этом. Есть риски. В отличие от JSON, который возвращает объекты, JSONP фактически вызывает функцию JS и выполняет код напрямую. Это означает, что наличие вредоносного сайта может нанести ущерб. Я бы не стал особо волноваться по поводу прогноза.Ио, но если это какой-то сомнительный русский мп3сайт, то я был бы осторожен! Как это работает, он вставляет тег <script src="http://forecast.io/blah/blah/blah/?callback=jquery_12345" ></script> на вашу страницу. Теги сценария не имеют такого же ограничения по происхождению. Этот файл в основном оборачивает объект JSON в вызов jquery_12345, который jQuery абстрагирует для вас, поэтому он работает как обычно. Другой недостаток, помимо безопасности, заключается в том, что нет хорошего способа обнаружить сбой. JQuery поможет, имея тайм-аут, который он может использовать, чтобы «предполагать» сбой, но вы не получите ошибку 500 или что-то подобное, как в случае с истинным JSON.

person dmeglio    schedule 02.05.2015
comment
Я изменил ключ API перед публикацией. Чтобы показать лучший пример, я заменил строку privateAPIKey в переменной. - person safron6; 02.05.2015
comment
где именно этот оператор ?callback=? войти в код? или хотя бы указать на строку, чтобы добавить его, я не уверен. - person safron6; 02.05.2015
comment
Конечно, var darkForecastAPI= "https://api.forecast.io/forecast/" + currentAPIKey + "/" + locations + "," + time +"?callback=?"; Это параметр строки запроса. - person dmeglio; 02.05.2015
comment
Кстати, суть ключа API заключается не в том, что вы публикуете его в stackoverflow, он становится общедоступным, потому что все, что мне нужно сделать, это просмотреть исходный код на вашей веб-странице, и я могу его украсть. Тогда я мог бы злоупотребить вашим ключом API и забанить вас в прогнозе.Ио. Вот почему они рекомендуют вам настроить прокси-сервер на стороне сервера, который будет скрывать ключ API со стороны клиента. - person dmeglio; 02.05.2015
comment
Великий и спасибо за вашу помощь и мудрость. Ошибка перекрестного происхождения исчезла, но теперь у меня возникла небольшая проблема с отладкой. Как бы вы спросили с оператором &&, что оба условия должны быть истинными в длинном сценарии JSON с текущим Wx, и он должен быть прочитан как дождь? Я получаю неопределенный возврат в firebug, но код, кажется, имеет смысл в контексте типа С# (с которым я более знаком). - person safron6; 02.05.2015
comment
Вы думаете, что APIkey виден в коде javascript? Я еще не реализовал это на сервере, если я это сделаю. Пока это частный калькулятор. Хотя кто-то мог ругать то, что у меня сейчас есть- но я его сбросил. (ууу) - person safron6; 02.05.2015
comment
Ключ API будет виден в источнике, а также в функции сетевого монитора браузера. Что касается вашего вопроса о неопределенной переменной, можете ли вы объяснить больше? Не уверен, что следую. && работает в JavaScript так же, как и в C#. - person dmeglio; 02.05.2015
comment
JSON выглядит следующим образом: в настоящее время: { время: 1429545600, сводка: преимущественно облачно, значок: переменная облачность, интенсивность осадков: 0,0076, вероятность осадков: 0,32, тип осадков: дождь, температура: 42,33, кажущаяся температура: 42,33, точка росы: 39,47, влажность: 0,9, скорость ветра: 0,26, азимут ветра: 143, видимость: 7,19, облачность: 0,74, давление: 984,94, озон: 338,05 }, - person safron6; 02.05.2015
comment
Для дождя и precipIntensity может быть более одного из этих тегов, особенно если я реализую почасовой прогноз - person safron6; 02.05.2015
comment
Давайте продолжим обсуждение в чате. - person dmeglio; 02.05.2015

Вы пытаетесь вызвать URL-адрес, обслуживаемый доменом api.forecast.io, который отличается от домена, из которого исходит ваш код javascript, следовательно, это междоменный запрос.

Другой домен не поддерживает CORS. Это можно решить, добавив заголовок ACAO другим доменом.

CORS

person Sameer Naik    schedule 02.05.2015
comment
Не знаком с шапкой ACAO, объясните подробнее, что вы думаете о решении. - person safron6; 02.05.2015
comment
@safron6 safron6 это не решение, потому что заголовок ACAO должен быть добавлен на стороне прогноза. Io, а не на вашей. Они не собираются этого делать. Смотрите мой ответ ниже, он может указать вам правильное направление. Если у вас есть дополнительные вопросы, я буду рад помочь. - person dmeglio; 02.05.2015

Вместо того, чтобы выполнять вызов Ajax в JavaScript на стороне клиента, вы можете сделать это в коде на стороне сервера и не иметь дело с CORS. Google: прокси-сервер CORS {ваш серверный язык}

person Ram Vennam    schedule 02.05.2015

Здесь вам не нужно ничего особенного, так как запрос может быть выполнен менее чем в 10 строках простого старого Javascript. Нажмите «Выполнить фрагмент кода» ниже, чтобы проверить.

Другой альтернативой является использование Yahoo, который будет возвращать 1000 прогнозов в день без ключа API. Подробнее здесь: Погода Yahoo

    <html>
    <head>
         <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/json2/20140204/json2.min.js"></script>
    </head>
    <body>
    
    <xmp id="stdout"></xmp>
    <script type="text/javascript">
    
    	function callback( data ) {
    		// do something with the forecast data 
    		document.getElementById('stdout').innerHTML = JSON.stringify( data, null, '\t' );	
    	}
    
    	var head = document.head || document.getElementsByTagName('head')[0] || document.documentElement;
    	var script = document.createElement('script');
    	script.type = 'text/javascript';
    	script.src = 'https://api.forecast.io/forecast/c52dea83654f200f77cf97db47fdd03e/46.3494,-85.5083?callback=callback'
    	head.appendChild(script);
    
    </script>
    </body>
    </html>

person Roberto    schedule 02.05.2015