我试图通过Safari扩展程序从Reddit加载一些数据。我使用JSONP模式创建回调函数并将新的src附加到脚本。但是,看起来有两个窗口命名空间,并且我动态创建的函数不可用于动态添加的脚本的上下文。
此链接似乎详细说明了chrome的问题,我猜测它与我的相似。
JSONP request in chrome extension, callback function doesn't exist?
这里是代码(在扩展名之外工作):
function jsonp(url, callback) {
var callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
window[callbackName] = function(data) {
delete window[callbackName];
callback(data);
};
console.log('about to create script');
var script = document.createElement('script');
script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'jsonp=' + callbackName;
document.body.appendChild(script);
console.log('script should be appended');
}
function getImages(){
jsonp('http://www.reddit.com/r/cats/.json', function(data) {
data.data.children.forEach(function(el){
console.log(el.data.url);
});
});
}
任何想法,解决方法?
谢谢!
答案 0 :(得分:2)
你在同一个窗口中有两个名称空间是对的。注入的脚本无法访问网页的全局变量,反之亦然。当您在注入的脚本中启动JSONP时,插入的<script>
标记的脚本将在网页的命名空间中运行。
我知道有两种方法可以在Safari扩展中解决此限制。
可能更好的方法是使用扩展程序的全局页面通过标准XHR或jQuery Ajax方法(全局页面脚本支持)与外部API通信,并使用messages将获取的数据传递给注入脚本。
另一种方法是继续使用注入脚本中的JSONP,但是让JSONP回调函数将获取的数据添加到页面的DOM中,注入的脚本可以访问 。例如,您可以将数据放在隐藏的<pre>
元素中,然后使用元素的innerHTML
属性来检索它。当然,这种技术确实使内容对页面自己的脚本可见,因此请谨慎操作。