从Safari扩展创建JSONP回调

时间:2014-10-23 18:09:23

标签: javascript safari jsonp safari-extension

我试图通过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);
        });
    });    
}

任何想法,解决方法?

谢谢!

1 个答案:

答案 0 :(得分:2)

你在同一个窗口中有两个名称空间是对的。注入的脚本无法访问网页的全局变量,反之亦然。当您在注入的脚本中启动JSONP时,插入的<script>标记的脚本将在网页的命名空间中运行。

我知道有两种方法可以在Safari扩展中解决此限制。

可能更好的方法是使用扩展程序的全局页面通过标准XHR或jQuery Ajax方法(全局页面脚本支持)与外部API通信,并使用messages将获取的数据传递给注入脚本。

另一种方法是继续使用注入脚本中的JSONP,但是让JSONP回调函数将获取的数据添加到页面的DOM中,注入的脚本可以访问 。例如,您可以将数据放在隐藏的<pre>元素中,然后使用元素的innerHTML属性来检索它。当然,这种技术确实使内容对页面自己的脚本可见,因此请谨慎操作。