从Safari扩展创建JSONP回调

Creating a JSONP Callback From Safari Extension

本文关键字:JSONP 回调 创建 扩展 Safari      更新时间:2023-09-26

我正试图通过Safari扩展从Reddit加载一些数据。我使用JSONP模式来创建回调函数,并将新的src附加到脚本中。但是,看起来有两个窗口名称空间,并且我动态创建的函数对于动态添加的脚本的上下文不可用。

这个链接似乎详细说明了chrome的问题,我猜它与Safari中的类似。

chrome扩展中的JSONP请求,回调函数不';不存在?

这是代码(在扩展之外工作):

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);
        });
    });    
}

有什么想法,解决办法吗?

谢谢!

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

我知道有两种方法可以在Safari扩展中绕过这个限制。

可能更好的方法是使用扩展的全局页面通过标准XHR或jQueryAjax方法(在全局页面脚本中支持这些方法)与外部API通信,并使用消息将提取的数据传递给注入的脚本。

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