2013-04-22 2 views
0

Чтобы загрузить некоторые данные geojson, мне нужно использовать исходные скрипты во внешнем домене, скажем http://www.stat.ucla.edu/~jeroen/files/la_county_simplified.min.json. Я не контролирую содержание этого скрипта; все, что я знаю, это адрес и имя объекта, определенного в сценарии, что я заинтересован в фиктивный версии сценария выглядит следующим образом:.Элегантный способ извлечения объекта из междоменного скрипта

var my_data = {"foo" : 123, "bar" : 456} 

Теперь в моем приложении, я хотел бы, чтобы загрузить my_data динамически со своего URL-адреса. Поскольку это кросс-домен, я не могу использовать ajax. Это не совсем jsonp, потому что мой скрипт определяет объект, а не функцию. Один из способов - вставить его просто как <script> в начало текущего документа. Однако я хотел бы избежать возможных побочных эффектов.

Что было бы более чистым решением? Я думал создать , а затем вставить тег <script> в iframe и извлечь объект после загрузки iframe. Однако я не уверен, что это надежный метод, который будет работать с перекрестными браузерами (особенно привязка обратного вызова для извлечения объекта после загрузки сценария в iframe).

Есть ли библиотека или стандартное решение для загрузки сценария на чистой странице и извлечение копии по определенному объекту на главную страницу? У меня уже есть зависимость от jQuery, так что все будет хорошо.

+0

Я думаю, что вы хотите JSONP, который поддерживает jQuery с функциями $ .getJSON(), $ .get и $ .ajax – 2013-04-22 23:47:41

+0

Я думаю, что именно так JQuery реализует JSONP. – Barmar

+0

jsonp принимает имя функции как дополнение. У моего скрипта есть объект, а не функция. – Jeroen

ответ

2

Если вы планируете сделать это чисто на стороне клиента и не может форматировать данные, вы можете использовать JSONP с твист. Вместо того, чтобы модифицировать данные для соответствия обратному вызову, мы обновляем загрузчик, чтобы принять данные.

Мы слушаем сценарий onload. Когда скрипт загружается, переменная должна теперь находиться в глобальной области, и мы выполняем наш обратный вызов, который передает эту глобальную переменную в наш обратный вызов.

//your script loader 
function loadData(url,varName,callback){ 

    var script = document.createElement('script'); 
    document.getElementsByTagName('head')[0].appendChild(script); 

    //when the script loads, we pass in `window.my_data` 
    script.onload = function(){ 
    callback.call(this,window[varName]); 
    }; 
    script.src = url; 

} 

//using it 
loadData('http://example.com/somefile.js','my_data',function(data){ 
    //executes when script is loaded, where data is `my_data` 
}); 

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

+0

@ Jeroen обновил ответ. – Joseph

+0

Спасибо. Было бы безопаснее делать это в iframe или так? Я хочу избежать проблем, если какой-либо из таких скриптов должен содержать что-то недействительное или nameclash. – Jeroen

+0

@Jeroen Если файлы находятся в другом домене, только CORS или JSONP могут это сделать. AJAX ограничен одним и тем же доменом, кадры ограничены одним и тем же доменом. – Joseph

-1

JSON-P - это способ загрузки JavaScript из удаленного домена.

Формат возврата JavaScript предназначен для вызова функции с данными ответа в качестве параметра.

someGlobalFunctionName({/* your response data */}); 

function someGlobalFunctionName(data) { /* do something with data */ } 

Поскольку данные, содержащиеся в объекте и передается функции, не существует никакого глобального утечки, кроме самой глобальной функции, которая является неизбежным.

Подробнее: http://json-p.org/

+0

Внешний скрипт не содержит функции. Он определяет объект. Я не могу изменить содержимое скрипта. – Jeroen

+0

@ Jeroen вы должны попросить владельца сделать ресурс JSON-P совместимым. Если сценарий был предназначен для междоменного использования, это не должно быть проблемой. –

0

Нет другого способа обойти его, так как вы должны бить ту же самую исходную политику, что и загружать скрипт в новый тег скрипта, JSONP тоже работает, но jquery скрывает его для вас.

Либо это, либо сайт имеет Корс заголовки, если сайт не имеет Корса заголовков здесь, как вы можете загрузить данные (не используя JSONP, потому что это не в формате JSONP):

function loadJS(url){ 
    var s=document.createElement("script"); 
    s.src=url; 
    $(s).on("load",function(){ 
    console.log("var abvailable");//do something with the variable here 
    $(s).remove(); 
    }); 
    document.head.appendChild(s); 
} 
loadJS("http://code.jquery.com/jquery-1.9.1.min.js"); 
0

метод IFrame должен работать нормально:

  • создать IFRAME
  • впрыснуть тег сценария, который указывает на файл
  • по загрузке сценария, получить объект

Единственная проблема кросс-браузера, о которой я могу думать, это то, что вам нужно будет использовать addEventListener в современных браузерах и attachEvent в старом IE.

Это стандартное использование iframe в виде песочницы - если я правильно понимаю, вас беспокоят возможные конфликты с именами глобальных переменных.

[Update] Для того, чтобы решить некоторые из ваших комментариев, вот некоторые кросс-браузерный код:

Чтобы добавить слушатель события:

function addEvent(element,event,fn,capture){ 
// capture defaults to false if omitted 
if (element.addEventListener) {element.addEventListener(event,fn,(capture||false));} 
// else for old IE 
else {element.attachEvent('on'+event,fn);} 
}; 

Чтобы получить доступ к IFrame документа:

function iframeDocument(ifr){ 
var doc=ifr.contentWindow||ifr.contentDocument; 
if (doc.document) doc=doc.document; 
return doc; 
}; 

Если вы используете jQuery, .on("load") и $(ifr).contents() позаботятся об этих проблемах с совместимостью между браузерами.

Смежные вопросы