jQuery.getJSON внутри пользовательского скрипта greasemonkey - PullRequest
11 голосов
/ 30 октября 2009

Я пытаюсь написать сценарий пользователя, который выполняет междоменный запрос AJAX.

Я включил jQuery в свой скрипт, используя @require, и, кажется, все работает нормально до того момента, когда я пытаюсь запустить jQuery.getJSON.

API, к которому я обращаюсь, поддерживает jsonp, однако постоянно появляется сообщение о том, что jsonp123456789 не определено.

Из того, что мне удалось собрать, это связано с тем, что jQuery записывает ответ jsonp прямо в заголовок страницы, который затем становится изолированной программной средой. Как только это произошло, jQuery больше не может обращаться к обратному вызову, в результате чего он не определен. (Я не на 100% в этом случае, но мне это кажется вероятным).

Есть ли способ обойти это? Было предложено объявить функцию обратного вызова внутри unsafeWindow, но я не уверен, как это сделать, и не смог заставить ее работать.

Ответы [ 3 ]

16 голосов
/ 02 ноября 2009

Разве не было бы неплохо, если бы jQuery использовал GM_xmlhttpRequest внутри, чтобы вы могли пользоваться всеми удобствами методов jQuery и межсайтовой функциональностью Greasemonkey? Как указывает mahemoff, Greasemonkey может позволить вам сделать запрос, не полагаясь на JSONP и столкнувшись с проблемой обратного вызова, с которой вы сталкиваетесь, но вам придется самостоятельно разобраться с содержимым JSON.

Мы написали библиотеку, которая будет делать именно это: Greasemonkey / jQuery XHR bridge . Если вы @require этот сценарий в своем пользовательском сценарии, то все $.get и $.getJSON и $.post и т. Д. Вызовы jQuery будут работать на нескольких сайтах, не полагаясь на такие методы, как JSONP.

Так что, если вы используете этот мост и просто удалите ?callback=? из своего URL, ваш код jQuery должен работать без изменений. Это сообщение в блоге содержит пошаговое руководство. Если у кого-то есть какие-либо вопросы, комментарии, сообщения об ошибках или предложения по поводу плагина Bridge, пожалуйста, сообщите мне.

8 голосов
/ 30 октября 2009

Обходной путь должен использовать GM_HttpRequest. Вы можете сойти с рук вместо JSONP для междоменных запросов, потому что в отличие от обычного XHR, GM_HttpRequest разрешает междоменные вызовы. Вы хотите что-то вроде:

  GM_xmlhttpRequest({
     method: "GET",
     url: "http://example.com/path/to/json",
     onload: function(xhr) {
      var data = eval("(" + xhr.responseText + ")");
      // use data ...
    }
  });

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

К сожалению, вам также нужно обернуть казалось бы бесполезным setTimeout нулевой длительности вокруг всего этого. Я считаю, что проще всего вставить GM_xmlhttpRequest в его собственный метод, а затем запустить setTimeout (makeCall, 0);.

Вы можете увидеть реальный пример здесь .

1 голос
/ 01 сентября 2010

Как многие из вас знают, Google Chrome на данный момент не поддерживает ни одну из удобных функций GM_.

Таким образом, невозможно выполнять межсайтовые AJAX-запросы из-за различных ограничений песочницы (даже при использовании таких замечательных инструментов, как сценарий кросс-доменного запроса Джеймса Падолси )

Мне нужен был способ, чтобы пользователи знали, когда мой скрипт Greasemonkey был обновлен в Chrome (поскольку Chrome тоже этого не делает ...). Я нашел решение, которое описано здесь (и используется в моем скрипте Lighthouse ++ ), и его стоит прочитать тем, кто хочет проверить версию своих скриптов:

http://blog.bandit.co.nz/post/1048347342/version-check-chrome-greasemonkey-script

...