简体   繁体   中英

JSONP callback doesn't work

I wrote a Foo constructor, that have a load function for upload JSONP. script.src has a callback, but I've got an error: Uncaught ReferenceError: bar is not defined . How I can fix it?

function Foo(params) { 
    function bar(response) {
        console.log(response);
    }

    function load() {
        var script = document.createElement('script');
        script.src = Config.apiUrl + '&callback=bar';
        document.getElementsByTagName('head')[0].appendChild(script);
    }

    document.getElementById('button').addEventListener('click', load, false);
}

Usage:

var foo = new Foo(params);

Can be a lot of in the page.

assuming your JSONP-response is correct and looks like this:

bar(/*some argument*/);

the issue: bar must be global accessible, but currently it isn't(it's only visible inside Foo )

Possible workaround:

define bar as a method of Foo , then you be able to execute it(as long as the instance foo is global accessible). The callback -parameter must be set to foo.bar in this case:

function Foo(params) {

  this.bar=function(response) {
        console.log(response);
    }

  this.load=function(){
        var script = document.createElement('script');
        script.src = Config.apiUrl + '&callback=foo.bar';
        document.getElementsByTagName('head')[0].appendChild(script);
    }

    document.getElementById('button').addEventListener('click', this.load, false);
}

//assuming you create the instance in global scope
var foo = new Foo(params);

Short answer:

You should make bar function available globally or make it a public method of a Foo instance which should be available globally.

Since you have that error, you know that you need a server which returns a valid javascript code string like:

alert('JSONP in action'); bar('result');

on your /?callback=bar request.

So, as JSONP is just an odinary script load on your page, it has the same variable accessibility rules as any other .js file you load in the head section of your html and, obviously, you can't access a "private function" from a different .js file.

But what about "saving bar function reference for later use" feature (closure)?

  • you may ask

It doesn't apply here, because the scope of the bar function call is created outside from the Foo constructor - the bar function is called from a "different file", so no closure here.

Better solution:

Assuming you need to make Cross Origin requests ( CORS ) and you can make changes in your server side apps, it's better to set Access-Control-Allow-Origin rules on the server you're trying to reach from different domain name app. This will allow you to use usual XHR requests and have much more information about http status codes or send custom different requests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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