Static JSON files over CDN via JSONP

前端 未结 2 812
感动是毒
感动是毒 2021-02-04 12:52

I have a large amount of static/rarely changing data in JSON format. To improve my ASP.NET MVC application performance, I would like to move them to a CDN (Amazon Cloud Front).

相关标签:
2条回答
  • 2021-02-04 13:54

    Best Practice for jQuery JSONP

    In the docs for $.getJSON and $.ajax, the jsonp section notes that you can set the callback function name explicitly with the jsonpCallback config property. So if you want JsonWrapping(...) to be the function jquery expects inside of the jsonp response, you can tie things back up like so:

    $.ajax({
        url: 'http://blah.com/blah.json'​​​​​​​​​​​​​​​​​​​​​​​​,
        dataType: 'jsonp',
        cache: true,
        jsonpCallback: 'JsonWrapping'
    })
    .done(function(r) {
        status.text('It worked.');
    })
    .fail(function (a, b, c) {
        status.text('It failed.');
    });​​​​​​​​​​​​​​​​​​​​​​​​
    

    In the above example the expected callback function inside the jsonp response is now JsonWrapping(), which jQuery will emit for you, respond to by calling .done() above, and cleanup after itself - much cleaner than hard-coding JsonWrapping into the page.

    Dangers of Hard-Coding and Naming Suggestions

    An important thing to consider is if you plan to have many jsonp calls on a single page, and your jsonp wrapping functions are hard-coded in the jsonp files, you should at least vary your wrapping function by something, like filename. Otherwise you create an asynchrony problem. For example assume you had this code:

    function jsonp(url) {
        return $.ajax({
            url: url,
            dataType: 'jsonp'
            cache: true,
            jsonpCallback: 'JsonWrapping'
        });
    }
    
    jsonp('http://cdn.mine/one.jsonp')
    .done(...);
    
    jsonp('http://cdn.mine/two.jsonp')
    .done(...);
    

    One of these jsonp calls is going to finish before the other - it's impossible to know which - and jQuery is in an impossible situation where it can't know which .done() to call for which response. As a result you'll get some page loads where they're called correctly, and some where the data crisscrosses. The solution is to vary by something like filename, like:

    function jsonp(url, wrapper) {
        return $.ajax({
            url: url,
            dataType: 'jsonp'
            cache: true,
            jsonpCallback: wrapper
        });
    }
    
    jsonp('http://cdn.mine/one.jsonp', 'one')
    .done(...);
    
    jsonp('http://cdn.mine/two.jsonp', 'two')
    .done(...);
    

    So the response from two.jsonp would need to look like:

    two({...json object here...})
    

    How It Works

    The call at the beginning of this answer will make jQuery request the URL via GET like this:

    http://blah.com/blah.json?callback=JsonWrapping
    

    And expect this as the response:

    JsonWrapping({...object here...})
    

    I included cache: true above because this is on a CDN, and so, presumably is not meant to change very often. If you leave cache: true out, jQuery inserts a second querystring param meant for cache-busting, like:

    http://blah.com/blah.json?callback=JsonWrapping&_=1365175172440
    

    Which can ruin the point of a CDN. The goal of the second querystring parameter is to ensure the data isn't loaded from the browser cache, and, when it hits the server (the CDN in this case), the querystring is unique meaning it busts its cache as well.

    Outside your scenario where you're using a CDN, there are situations where jQuery's default functionality is desirable: For example, when you want to simulate POST functionality across to another domain, without violating Same-Origin policy, jsonp with this cache busting feature can get that done for you.

    If the server you're talking to expects something other than "callback" in the querystring for specifying the name of the callback function in the response, you can use the jsonp config property - for example jsonp: 'myname' would get you:

    http://blah.com/blah.json?myname=JsonWrapping
    
    0 讨论(0)
  • 2021-02-04 13:56

    I just found out this is somehow possible. I solved it like so:

    $(document).ready(function(){
        $.getJSON("http://example.com/staticjsonfile.json",function(data){
        //callback function isn't here
        }
    });
    function JsonWrapping(data){
        //It's really here
        alert(data);
    }
    

    This is not ideal, as you loose binding with the event that fired the Ajax request. So some hacking is required. However, it kinda gets the job done. I'd be very open to a better solution.

    0 讨论(0)
提交回复
热议问题