简体   繁体   English

我的原始JSONP上的回调范围是什么

[英]What is the scope of the callback on my vanilla JSONP

A little backstory, I'm using the Twitch (game streaming service) api to pull a list of followers from a channel on the site. 有点背景知识,我正在使用Twitch(游戏流服务)API从网站上的频道中提取关注者列表。 In order to get around the CORS rules I'm using JSONP. 为了绕开CORS规则,我使用JSONP。 Personally, I prefer to use vanilla javascript over libraries so I learned how to do it from the excellent article over on https://cameronspear.com/blog/exactly-what-is-jsonp/ . 就个人而言,我更喜欢在库中使用香草javascript,因此我从https://cameronspear.com/blog/exactly-what-is-jsonp/上的精彩文章中学到了如何使用它。

Below is my simplified javascript (the actual code probably isn't extremely necessary, but maybe it'll help to clarify my question afterward): 下面是我的简化javascript(实际代码可能不是非常必要,但也许以后可以帮助澄清我的问题):

//Function to pull JSONP

function pullJSONP(url) {

    var JSONPInstance = document.createElement('script');
    JSONPInstance.src = url;

    JSONPInstance.onload = function () {
        this.remove();
    };

    var head = document.getElementsByTagName('head')[0];
    head.insertBefore(JSONPInstance, null);
} 


//End function to pull JSONP


function storeCurrentFollows(offset) //Function to wrap entire operation
{


    function pullStartSessionFollows(JSONdata) //Callback from JSONP down below
    { 


        function pushNameElements(followEntry) //Function to add names into array
        {

            allSessionFollows.push(followEntry.user.name);

        }

        JSONdata.follows.forEach(pushNameElements); //Iterate through followers

        storeCurrentFollows(offset+100); //Rerun operation, incrementing offset by 100

    }; 

    if(offset > 300){ return }
    else
    {
        //running JSONP function from above, passing in url and setting a callback
        pullJSONP('https://api.twitch.tv/kraken/channels/' + channelName + '/follows?direction=desc&limit=100&offset=' + offset + '&callback=pullStartSessionFollows');

    }


}


storeCurrentFollows(0);

So my question is this, whenever I run this operation with the items in this order it returns the error > Uncaught ReferenceError: pullStartSessionFollows is not defined in the console. 所以我的问题是,每当我按此顺序对项目运行此操作时,都会返回错误> Uncaught ReferenceError: pullStartSessionFollows is not defined在控制台中> Uncaught ReferenceError: pullStartSessionFollows is not defined It doesn't work properly unless I move the pullStartSessionFollows function up into the global scope. 除非我将pullStartSessionFollows函数上移到全局范围内,否则它将无法正常工作。 What I don't understand is why it thinks it is undefined even though it is instantiated just before I run the pullJSONP() function. 我不明白的是,即使在运行pullJSONP()函数之前就实例化了它,为什么仍认为它是未定义的。 I don't want to move it because then I'll have to pass in my offset to two different functions as well as a few other issues. 我不想移动它,因为那样我必须将偏移量传递给两个不同的函数以及其他一些问题。 Any help or insight would be very much appreciated. 任何帮助或见解将不胜感激。 Thank you in advance! 先感谢您!

The function called as the JSONP callback has to be global (or a property of a global object). 称为JSONP回调的函数必须是全局的(或全局对象的属性)。 The callback expression returned as the response body from a JSONP service is evaluated in the global context. 在全局上下文中评估从JSONP服务作为响应主体返回的回调表达式。 The server is returning something that looks like 服务器返回的内容看起来像

pullStartSessionFollows({ ... });

Your function is defined inside that other function, so it's not global. 您的函数是在其他函数中定义的,因此不是全局的。

It doesn't work properly unless I move the pullStartSessionFollows function up into the global scope. 除非我将pullStartSessionFollows函数上移到全局范围内,否则它将无法正常工作。

Correct, JSONP callbacks must be global functions. 正确, JSONP回调必须是全局函数。 It's intrinsic to the way JSONP works. 它是JSONP工作方式的固有特性。

What I don't understand is why it thinks it is undefined even though it is instantiated just before I run the pullJSONP() function. 我不明白的是,即使在运行pullJSONP()函数之前就实例化了它,为什么仍认为它是未定义的。

Because that creates the function within the function where you do that ( storeCurrentFollows ), not as a global. 因为那样会在您执行此操作的函数( storeCurrentFollows )中创建函数,而不是全局函数。 But the way JSONP works requires that the function be global. 但是,JSONP的工作方式要求该函数是全局的。

You can have the pullStartSessionFollows function only exist while you have a pending JSONP call, by declaring it as a global variable: 通过将其声明为全局变量,可以使pullStartSessionFollows函数仅在进行未决JSONP调用时存在:

var pullStartSessionFollows;

...and then assigning to that within storeCurrentFollows : ...然后在storeCurrentFollows分配给它:

pullStartSessionFollows = function() { /* ... */ };

You can also remove it when the callback has done its work: 您还可以在回调完成其工作后将其删除:

pullStartSessionFollows = undefined;

Why must the callback function be a global? 为什么回调函数必须是全局的? Because the way JSONP works is by adding a script element to the page, as though you had written this in the HTML: 因为JSONP的工作方式是通过向页面添加脚本元素,就像您在HTML中编写的一样:

<script src="http://example.com/get?callback=pullStartSessionFollows"></script>

...and then the response looks like: ...然后响应看起来像:

pullStartSessionFollows({/*...JSON here...*/})

That requires that it be a global function. 这就要求它是一个全局功能。

jsonp回调必须位于全局javascript范围内,因为在请求完成时,无法确定回调函数的原始范围,这就是为什么它将在全局范围内执行的原因,该范围在任何范围内都可以访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM