jQuery.getJSON внутри пользовательского скрипта greasemonkey
-
22-07-2019 - |
Вопрос
Я пытаюсь написать сценарий пользователя, который выполняет междоменный запрос AJAX.
Я включил jQuery в свой сценарий, используя @require, и, кажется, все работает нормально до того момента, когда я пытаюсь запустить jQuery.getJSON.
API, к которому я обращаюсь, поддерживает jsonp, однако я получаю сообщение об ошибке, в котором говорится, что jsonp123456789 не определен.
Из того, что мне удалось собрать, это связано с тем, что jQuery записывает ответ jsonp прямо в заголовок страницы, который затем становится изолированной программной средой. Как только это произошло, jQuery больше не может обращаться к обратному вызову, в результате чего он не определен. (Я не на 100% в этом случае, но мне это кажется вероятным).
Есть ли способ обойти это? Было предложено объявить функцию обратного вызова внутри unsafeWindow, но я не уверен, как это сделать, и не смог заставить ее работать.
Решение
Разве не было бы неплохо, если бы jQuery использовал GM_xmlhttpRequest
внутри, чтобы вы могли пользоваться всеми удобствами методов jQuery и межсайтовой функциональностью Greasemonkey? Как указывает mahemoff, Greasemonkey может позволить вам сделать запрос, не полагаясь на JSONP и не столкнувшись с проблемой обратного вызова, с которой вы сталкиваетесь, но вам придется иметь дело с содержимым JSON самостоятельно.
Мы написали библиотеку, которая будет делать именно это: Greasemonkey / jQuery XHR bridge . Если вы @require
этот сценарий в своем пользовательском сценарии, то все $. Get
и $. GetJSON
и $. Post
и т. д. Вызовы jQuery будут работать на нескольких сайтах без использования таких методов, как JSONP Р>
Так что если вы используете этот мост и просто удалите ? callback =?
из своего URL, ваш код jQuery должен работать без изменений. Этот пост в блоге содержит пошаговое руководство. Если у кого-то есть какие-либо вопросы, комментарии, сообщения об ошибках или предложения по поводу подключаемого модуля моста, сообщите мне.
Другие советы
Обходной путь должен использовать 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);.
Как многие из вас знают, Google Chrome на данный момент не поддерживает ни одну из удобных функций GM_.
Таким образом, невозможно выполнять межсайтовые запросы AJAX из-за различных ограничений песочницы (даже с использованием таких замечательных инструментов, как сценарий кросс-доменного запроса Джеймса Падолси )
Мне нужен был способ, чтобы пользователи знали, когда мой скрипт Greasemonkey был обновлен в Chrome (так как Chrome тоже этого не делает ...). Я нашел решение, которое описано здесь (и используется в моем скрипте Lighthouse ++ ) и Стоит прочитать для тех, кто хочет проверить версию своих скриптов:
http://blog.bandit.co .nz / запись / 1048347342 / версия проверки хром-Greasemonkey-скрипт