SlexAxton / yepnope.js

A Script Loader For Your Conditional Builds
http://yepnopejs.com/
BSD 3-Clause "New" or "Revised" License
2.51k stars 323 forks source link

Firefox wants to load plugins to handle application/json... #18

Closed mkoistinen closed 13 years ago

mkoistinen commented 13 years ago

Hi,

Attempting to use yepnope to load a remote js (for twitter). The server responds with a MIME-type of "application/json". This works fine in most browsers, but in Firefox 3.6.1 (at least), the user is prompted to "Install Missing Plugins...". When I lazy load with jQuery, I don't have this issue.

I've tried creating a prefix 'js!' to force the type to JS, but it doesn't seem to have any affect. Here's some code to work with:

var twitterid = 'some_twitter_id';

yepnope.addPrefix('js', function (res) {
  res.forceJS = true;
  return res;
});
yepnope({
  test: window.twitterCallback2,
  nope: "js!http://twitter.com/javascripts/blogger.js",
  complete: function() {
    yepnope('js!http://twitter.com/statuses/user_timeline/' + twitterid +'.json?callback=twitterCallback2&count=3')
  }
});

This is the jQuery code that works fine:

if (!window.twitterCallback2) {
  $.getScript("http://twitter.com/javascripts/blogger.js", function() {
    $.getScript('http://twitter.com/statuses/user_timeline/' + twitterid +'.json?callback=twitterCallback2&count=3');
  });
}
else {
  $.getScript('http://twitter.com/statuses/user_timeline/' + twitterid +'.json?callback=twitterCallback2&count=3');
}

This doesn't cause the 'missing plugin' issues, but its not as DRY either. =(

ralphholzmann commented 13 years ago

Heyo,

So after looking into this issue, there's definitely a header being sent back by twitter that is prompting the pop-up. I can't tell which specifically, but I assume it has something to do with the mime / content-type.

That being said, yepnope isn't really designed to be loading json callbacks. While it may work if the headers are correct, typically JSON is sent with a no-cache header, and yepnope requires that there always be proper caching on the resources it loads. This is because yepnope fully decouples preloading and executing. This technique hinges on the fact that we can preload a resource, and then quickly execute it because its already loaded into the browsers cache. In the case of loading JSON, we cant preload the data because it's being sent with a no-cache header, so you would essentially be downloading the JSON twice (this is also the case with any resources that doesn't have proper caching headers).

Using jQuery to grab the json in the callback would be the best option here:

var twitterid = 'some_twitter_id';

yepnope({
  test: window.twitterCallback2,
  nope: "js!http://twitter.com/javascripts/blogger.js",
  complete: function() {
    $.getScript('http://twitter.com/statuses/user_timeline/' + twitterid +'.json?callback=twitterCallback2&count=3')
  }
});

Perhaps we can add this to the "gotchas" or "keep in mind" section on the site.

Thanks,

Ralph

mkoistinen commented 13 years ago

Fair points!