关于 javascript:从 Safari 扩展创建 JSONP 回调

Creating a JSONP Callback From Safari Extension

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

此链接似乎详细说明了 chrome 的问题,我猜这与我在 Safari 中的问题相似。

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 时,插入的 标记的脚本会在网页的命名空间中运行。

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

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

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