Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Easier CDN fallback support and IE 6-8 fix #48

Closed
wants to merge 5 commits into from
Closed

Easier CDN fallback support and IE 6-8 fix #48

wants to merge 5 commits into from

Conversation

willfarrell
Copy link

See commit comments for details.

use case example:
```js
$script(cdnSrc.Modernizr, 'Modernizr', function() {
	//code
}, cdnFallback);

function cdnFallback(depsNotFound) {
	var i = depsNotFound.length;
	while (i--) {
		console.log('cdnFallback '+depsNotFound[i]);
		$script(cdnFallbackSrc[depsNotFound[i]], depsNotFound[i]);
	}
}
```

Currently to allow fallback the documentation suggest something along the lines of
```js
$script(cdnSrc.Modernizr, 'Modernizr');
$script.ready('Modernizr', function() {
	console.log('Modernizr ready');
	
	modernizrFallback(Modernizr);
	bootstrap();
}, cdnFallback);
```
However this will load the both the CDN file and the fallback file.

This commit separates out the onerror callbacks to allow
calling a fallback function.
Array.forEach is not supported in IE 6-8. `while(i--)` is the fastest way to go through a loop.
@ded
Copy link
Owner

ded commented Apr 9, 2013

right on. can you add examples to the README and adhere to the style of the code (or if you'd rather, i can point out the nits)

@willfarrell willfarrell mentioned this pull request Apr 10, 2013
@willfarrell
Copy link
Author

Done

@CMCDragonkai
Copy link

This will really be useful, but could you add it into the README separation between the different examples, I would like to see a more complete example of different cdn fallbacks. And can this be merged?

@CMCDragonkai
Copy link

BTW, I tested your pull request, and I'm finding that depsNotFound is always the full id array. There's no differentiation between which exact dependency failed. It would be great if there was some form of distinction. That way you could use a single call to $script and depending on which one failed, it will make the appropriate fallback. Right now you have to make multiple calls to $script.

- script.js update to match current repo branch + support for `script('src', function(){}, fallback)`
- testing added
@willfarrell
Copy link
Author

@CMCDragonkai A small clean up to the README is uploaded

You are correct there are multiple calls to $script, please create this as a unique issue and if you can a pull request (Check out $script.ready). Note the browser will only make one http call per unique url, so not too critical.

@willfarrell willfarrell mentioned this pull request Jul 31, 2013
@ded
Copy link
Owner

ded commented Aug 14, 2013

k, will have a look at this now and try to sort out the conflict

@esnellman
Copy link

Exactly what I was looking but 1 Issue
$script('//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js.NOTFOUND', 'jquery',
function() {
console.log('cloudflare worked');
},
function() {
console.log('cloudflare failed');
$script('//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js', 'jquery',function() {
console.log('googleapis worked');
},function() {
console.log('googleapis failed');
});
});
$script.ready('jquery', function() {
console.log('jquery is ready!');
});
output:
cloudflare failed
googleapis worked
jquery is ready!
cloudflare worked
jquery is ready!

fix that worked for me:
replace the 2 instances of
fb && $script.ready(id,fn,fb)
with
fb && fb()

Also 1 thing unrelated when i minify the source after the change
"http://closure-compiler.appspot.com/home" said says"JSC_USELESS_CODE: Suspicious code. The result of the 'not' operator is not being used. at line 106 character 10
ready() : !function (key) {"

Also the fallback will not work in IE8 but it does work in IE10.

@willfarrell
Copy link
Author

@esnellman The output you provided is correct based on your code. You have two/three jquery ready callbacks set (cloudflare worked, googleapi worked and jquery ready). Try the code below instead.

The CDN fallback feature was intended for falling back to a file stored on your own server (but it will still handle falling back to another CDN of course). Having this setup is faster than falling back to another CDN. Every time you include a resource from a different URL an additional DNS lookup is required (they are costly). Generally I only use a remote CDN if I have three or more popular resources that need to be loaded.

$script('//cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js.NOTFOUND', 'jquery', function() {
    console.log('cloudflare worked');
        console.log('jquery is ready!');
}, function() {
    console.log('cloudflare failed');
    $script('//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js', 'jquery', function() {
        console.log('googleapis worked');
    }, function() {
        console.log('googleapis failed');
    });
});

I'll check out your suggested change to fb && fb() and recheck IE8 this weekend.

PS Closure, as far I remember from what my friends at Google told me, is old and no longer worked on. Everyone uses uglify now, typically run when compiling an app using grunt.

@esnellman
Copy link

I got 3-5 so far, bootstrap, fontawesome, jquery, respond, html5shiv

Will make a note to use uglify.

simplified issue:

$script('path', 'jquery', function() {
    //BUG, called if a script is loaded with the same name in the fallback
}, function() {
    $script('path2', 'jquery');
});
$script.ready('jquery', function() {
  //BUG gets called twice if fallback gets a script with the same name to load
});

@bryanlarsen
Copy link

Perhaps the README should include some motivation. One of the most common CDN's is S3 + Cloudfront. However, CORS is not well supported by S3 + Cloudfront due to this issue: https://forums.aws.amazon.com/thread.jspa?threadID=114646

There is a workaround available, but it gets broken if a spider or "hacker" downloads a file without sending the origin header. Cloudfront then caches these invalid response headers and sends them to everybody behind that edge location resulting in a completely broken application. We've had significant downtime with some clients because of this issue. This PR in theory would have allowed us to continue to use $script without losing the benefits of a CDN. If this issue was called out in the README perhaps we would have known to actually set things up this way rather than learning the lesson the hard & expensive way.

@rych
Copy link

rych commented Mar 18, 2014

+1
Any chance this might be merged ?

@willfarrell
Copy link
Author

I feel the industry has moved past the need for this PR. Any objections to me closing this?

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants