GoogleでホストされているjQuery (または他のGoogleがホストされているライブラリ)をロードしようとすると、どうしたらよいでしょうか。
グーグルがフレークだと言っているのではない。 Googleのコピーがブロックされている場合があります(たとえば、イランなど)。
タイマーを設定してjQueryオブジェクトをチェックしますか?
両方のコピーが届く危険性は何でしょうか。
「Googleのものだけを使う」や「自分のものだけを使う」などの答えを探しているのではない。私はそれらの議論を理解しています。また、ユーザーがGoogleのバージョンをキャッシュしている可能性が高いことも理解しています。私はクラウド全般のフォールバックについて考えています。
編集:この部分を追加しました...
Googleはgoogle.loadを使用してajaxライブラリをロードすることを推奨しており、完了するとコールバックを実行するので、それがこの問題をシリアル化するための鍵になるのかどうかと思います。
ちょっとクレイジーに聞こえますね。信頼できる方法でできるかどうかを判断しようとしているだけです。
更新:jQueryは現在MicrosoftのCDNでホストされています。
あなたはこれのようにそれを達成することができます:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="/path/to/your/jquery"><\/script>');
</script>
これはあなたのページの<head>
内にあるべきであり、エラーを避けるためにすべてのjQuery対応イベントハンドラは<body>
内にあるべきです(それは絶対確実ではありません!)。
not GoogleがホストするjQueryを使用するもう1つの理由は、国によってはGoogleのドメイン名が禁止されているためです。
これを行う最も簡単でわかりやすい方法:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="path/to/your/jquery"><\/script>')</script>
これは私のために働くようです:
<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
// has the google object loaded?
if (window.google && window.google.load) {
google.load("jquery", "1.3.2");
} else {
document.write('<script type="text/javascript" src="http://joecrawford.com/jquery-1.3.2.min.js"><\/script>');
}
window.onload = function() {
$('#test').css({'border':'2px solid #f00'});
};
</script>
</head>
<body>
<p id="test">hello jQuery</p>
</body>
</html>
それが機能する方法は、 http://www.google.com/jsapi を呼び出すgoogle
オブジェクトを使用してwindow
オブジェクトにロードすることです。そのオブジェクトが存在しない場合、Googleへのアクセスは失敗していると考えられます。その場合はdocument.write
を使ってローカルコピーをロードします。 (この場合は自分のサーバーを使用しています。これをテストするには自分のサーバーを使用してください)
私はまたwindow.google.load
の存在をテストします - 私はtypeof
チェックを行うことで物事が適切なものであることを確認することもできます。しかし、これでうまくいくと思います。
テストしているHTMLページ全体を投稿してからコードの強調表示が失敗するように見えるので、これは単にロードロジックです。
if (window.google && window.google.load) {
google.load("jquery", "1.3.2");
} else {
document.write('<script type="text/javascript" src="http://joecrawford.com/jquery-1.3.2.min.js"><\/script>');
}
私が言わなければならないけれども、これがあなたのサイト訪問者にとっての懸念であるならばあなたは Google AJAX Libraries API をいじるべきであるかどうかわからない。
おかしな事実 :私は最初、さまざまなバージョンでこのためにtry..catchブロックを使用しようとしましたが、これほどきれいな組み合わせを見つけることができませんでした。他の実装も見たいです。純粋に練習として、このアイデアの。
あなたのサイトにmodernizr.jsが埋め込まれている場合は、組み込みのyepnope.jsを使ってスクリプトを非同期的にロードすることができます。
Modernizr.load([{
load : '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'
},{
test : window.jQuery,
nope : 'path/to/local/jquery-1.7.2.min.js',
both : ['myscript.js', 'another-script.js'],
complete : function () {
MyApp.init();
}
}]);
これはGoogle CDNからjQueryをロードします。その後、jQueryが正常にロードされたかどうかがチェックされます。そうでない場合( "nope")、ローカルバージョンがロードされます。あなたの個人用スクリプトもロードされています - "both"は、ロードプロセスがテストの結果とは無関係に開始されることを示します。
すべてのロードプロセスが完了すると、 'MyApp.init'の場合は関数が実行されます。
私は個人的にはこのような非同期スクリプトの読み込み方法を好みます。また、サイトを構築する際にmodernizrが提供する機能テストに頼っているので、とにかくサイトに埋め込んでいます。そのため、実際にはオーバーヘッドはありません。
ここにいくつかのすばらしい解決策があります、しかし私はローカルファイルに関してそれをもう一歩進めたいと思います。
Googleが失敗したシナリオでは、ローカルソースをロードする必要がありますが、おそらくサーバー上の物理ファイルは必ずしも最良の選択肢ではありません。私は現在同じソリューションを実装しているのでこれを出します。データソースによって生成されるローカルファイルにフォールバックしたいだけです。
これが私の理由は、私がGoogleからロードしたものとローカルサーバー上にあるものとを追跡することになるとき、私はいくらかの心を持っていたいということです。バージョンを変更したい場合は、ローカルコピーをGoogleからロードしようとしているものと同期させておく必要があります。多くの開発者がいる環境では、最善のアプローチは、設定ファイルのバージョン番号を変更するだけで済むように、このプロセスを自動化することだと思います。
これが私の提案した解決策で、理論上はうまくいくはずです。
理論的には、私のコードが適切に書かれていれば、私がする必要があるのは私のアプリの設定でバージョン番号を変更することです。自動化されたフォールバックソリューションがあり、サーバー上に物理ファイルを維持する必要はありません。
みんなはどう思いますか?これはやり過ぎるかもしれませんが、AJAXライブラリを管理する上品な方法になるかもしれません。
どんぐり
if (typeof jQuery == 'undefined') {
// or if ( ! window.jQuery)
// or if ( ! 'jQuery' in window)
// or if ( ! window.hasOwnProperty('jQuery'))
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = '/libs/jquery.js';
var scriptHook = document.getElementsByTagName('script')[0];
scriptHook.parentNode.insertBefore(script, scriptHook);
}
CDNからGoogleのコピーを含めようとした後。
HTML5では、type
属性を設定する必要はありません。
また使用することができます...
window.jQuery || document.write('<script src="/libs/jquery.js"><\/script>');
ローカルファイルを最後の手段として使用することをお勧めします。
今のところjQuery自身のCDNはhttpsをサポートしていないようです。もしそうなら、あなたはそれから最初にそこからロードしたいかもしれません。
シーケンスは次のとおりです。GoogleCDN => Microsoft CDN =>あなたのローカルコピー。
<!-- load jQuery from Google's CDN -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<!-- fallback to Microsoft's Ajax CDN -->
<script> window.jQuery || document.write('<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.3.min.js">\x3C/script>')</script>
<!-- fallback to local file -->
<script> window.jQuery || document.write('<script src="Assets/jquery-1.8.3.min.js">\x3C/script>')</script>
最新/従来のjQueryバージョンとフォールバックを条件付きでロードします。
<!--[if lt IE 9]>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="/public/vendor/jquery-legacy/dist/jquery.min.js">\x3C/script>')</script>
<![endif]-->
<!--[if gte IE 9]><!-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="/public/vendor/jquery/dist/jquery.min.js">\x3C/script>')</script>
<!--<![endif]-->
グーグルの禁止問題のために、私はマイクロソフトのcdn http://www.asp.net/ajaxlibrary/cdn.ashx を使うのを好む。
jQuery
変数を確認してください)ASP.NET MVC 5を使用している人々のために、jqueryのためにCDNを有効にするためにあなたのBundleConfig.csにこのコードを加えてください:
bundles.UseCdn = true;
Bundle jqueryBundle = new ScriptBundle("~/bundles/jquery", "//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js").Include("~/Scripts/jquery-{version}.js");
jqueryBundle.CdnFallbackExpression = "window.jQuery";
bundles.Add(jqueryBundle);
更新:
この答えは間違っていることがわかりました。本当の説明はコメントを見てください。
あなたのほとんどの質問は答えられました、しかし最後の部分に関しては:
両方のコピーが届く危険性は何でしょうか。
本当にありません。あなたは帯域幅を浪費するでしょう、2番目の無駄なコピーをダウンロードするのに数ミリ秒を追加するかもしれませんが、それらが両方とも通過するなら実際の害はありません。もちろん、上記のテクニックを使ってこれを避けるべきです。
これはこれについてのすばらしい説明です。
ロードの遅延とタイムアウトも実装しています。
http://happyworm.com/blog/2010/01/28/a-simple-and-robust-cdn-failover-for-jquery-14-in-one-line/
JQueryがまだロードされていない場合は動的にロードするGistを作成しました。ソースが失敗した場合は、(多くの回答からまとめて)フォールバックに進みます。 https://Gist.github.com/tigerhawkvok/9673154
私はそれが価値があるもののために、この答えではなく要旨を最新にしておくつもりであることに注意してください!
/* See https://Gist.github.com/tigerhawkvok/9673154 for the latest version */
function cascadeJQLoad(i) { // Use alternate CDNs where appropriate to load jQuery
if (typeof(i) != "number") i = 0;
// the actual paths to your jQuery CDNs
var jq_paths = [
"ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js",
"ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.min.js"
];
// Paths to your libraries that require jQuery
var dependent_libraries = [
"js/c.js"
];
if (window.jQuery === undefined && i < jq_paths.length) {
i++;
loadJQ(jq_paths[i], i, dependent_libraries);
}
if (window.jQuery === undefined && i == jq_paths.length) {
// jQuery failed to load
// Insert your handler here
}
}
/***
* You shouldn't have to modify anything below here
***/
function loadJQ(jq_path, i, libs) { //load jQuery if it isn't already
if (typeof(jq_path) == "undefined") return false;
if (typeof(i) != "number") i = 1;
var loadNextJQ = function() {
var src = 'https:' == location.protocol ? 'https' : 'http';
var script_url = src + '://' + jq_path;
loadJS(script_url, function() {
if (window.jQuery === undefined) cascadeJQLoad(i);
});
}
window.onload = function() {
if (window.jQuery === undefined) loadNextJQ();
else {
// Load libraries that rely on jQuery
if (typeof(libs) == "object") {
$.each(libs, function() {
loadJS(this.toString());
});
}
}
}
if (i > 0) loadNextJQ();
}
function loadJS(src, callback) {
var s = document.createElement('script');
s.src = src;
s.async = true;
s.onreadystatechange = s.onload = function() {
var state = s.readyState;
try {
if (!callback.done && (!state || /loaded|complete/.test(state))) {
callback.done = true;
callback();
}
} catch (e) {
// do nothing, no callback function passed
}
};
s.onerror = function() {
try {
if (!callback.done) {
callback.done = true;
callback();
}
} catch (e) {
// do nothing, no callback function passed
}
}
document.getElementsByTagName('head')[0].appendChild(s);
}
/*
* The part that actually calls above
*/
if (window.readyState) { //older Microsoft browsers
window.onreadystatechange = function() {
if (this.readyState == 'complete' || this.readyState == 'loaded') {
cascadeJQLoad();
}
}
} else { //modern browsers
cascadeJQLoad();
}
文字列の最後の<から\ x3Cをエスケープする必要があると思います。ブラウザから見ると、これはスクリプトブロックの終わりであると見なされます(HTMLパーサーはJavaScriptを認識していないため、文字列に表示されるものと実際にスクリプトを終了させるものを区別できません素子)。そのため、HTMLページ内の文字通りにJavaScriptで表示されると、(最善の場合)エラーが発生し、(最悪の場合)重大なセキュリティホールとなります。
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js"></script>
<script>window.jQuery || document.write('<script src="js/jquery-2.0.0.min.js">\x3C/script>')</script>
Google Hosted jQuery
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
バックアップ/フォールバック計画!
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>if (!window.jQuery) { document.write('<script src="/path/to/your/jquery"><\/script>'); }
</script>
参照: http://websitespeedoptimizations.com/ContentDeliveryNetworkPost.aspx
if (typeof jQuery == 'undefined')) { ...
または
if(!window.jQuery){
ブラウザがこの状態を通過し、それでもまだjQueryを必要とする残りのjavascriptをダウンロードしてエラーを返すので、CDNバージョンがロードされていないと動作しません。解決策はその条件でスクリプトを読み込むことでした。
<script src="http://WRONGPATH.code.jquery.com/jquery-1.4.2.min.js" type="text/javascript"></script><!-- WRONGPATH for test-->
<script type="text/javascript">
function loadCDN_or_local(){
if(!window.jQuery){//jQuery not loaded, take a local copy of jQuery and then my scripts
var scripts=['local_copy_jquery.js','my_javascripts.js'];
for(var i=0;i<scripts.length;i++){
scri=document.getElementsByTagName('head')[0].appendChild(document.createElement('script'));
scri.type='text/javascript';
scri.src=scripts[i];
}
}
else{// jQuery loaded can load my scripts
var s=document.getElementsByTagName('head')[0].appendChild(document.createElement('script'));
s.type='text/javascript';
s.src='my_javascripts.js';
}
}
window.onload=function(){loadCDN_or_local();};
</script>
JQueryのバックオフのためにdocument.write("<script></script>")
を書くのはより簡単に思えますが、Chromeはその場合検証エラーを与えます。だから私は "script" Wordを壊すことを好む。だから上のように安全になります。
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.1.min.js"></script>
<script>if (typeof jQuery === "undefined") {
window.jqFallback = true;
document.write("<scr"+"ipt src='http://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js'></scr"+"ipt>");
} </script>
長期的な問題については、JQueryのフォールバックを記録することをお勧めします。上記のコードでは、最初のCDNが利用できない場合、JQueryは別のCDNからロードされます。しかし、あなたはその誤ったCDNを知り、それを永久に削除することができます。 (このケースは非常に例外的なケースです)また、フォールバックの問題をログに記録することをお勧めします。だからあなたはAJAXで間違ったケースを送ることができます。 JQueryが定義されていないため、AJAX requestにはVanilla javascriptを使用する必要があります。
<script type="text/javascript">
if (typeof jQuery === 'undefined' || window.jqFallback == true) {
// XMLHttpRequest for IE7+, Firefox, Chrome, Opera, Safari
// ActiveXObject for IE6, IE5
var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
var url = window.jqFallback == true ? "/yourUrl/" : "/yourUrl2/";
xmlhttp.open("POST", url, true);
xmlhttp.send();
}
</script>
あなたの制御を超えて外部データストアからリソースをロードできないことは困難です。欠落している機能を探すことは、ここで説明されているように、タイムアウトの発生を回避する手段として完全に間違っています: http://www.tech-101.com/support/topic/4499-issues-using-a-cdn/
ASP.NETでRazor構文を使用して、このコードはフォールバックサポートを提供し、仮想ルートで機能します。
@{var jQueryPath = Url.Content("~/Scripts/jquery-1.7.1.min.js");}
<script type="text/javascript">
if (typeof jQuery == 'undefined')
document.write(unescape("%3Cscript src='@jQueryPath' type='text/javascript'%3E%3C/script%3E"));
</script>
あるいは、ヘルパーを作ります( ヘルパーの概要 ):
@helper CdnScript(string script, string cdnPath, string test) {
@Html.Raw("<script src=\"http://ajax.aspnetcdn.com/" + cdnPath + "/" + script + "\" type=\"text/javascript\"></script>" +
"<script type=\"text/javascript\">" + test + " || document.write(unescape(\"%3Cscript src='" + Url.Content("~/Scripts/" + script) + "' type='text/javascript'%3E%3C/script%3E\"));</script>")
}
そしてこれを次のように使います。
@CdnScript("jquery-1.7.1.min.js", "ajax/jQuery", "window.jQuery")
@CdnScript("jquery.validate.min.js", "ajax/jquery.validate/1.9", "jQuery.fn.validate")
次のようなコードを使うことができます。
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>window.jQuery || document.write('<script type="text/javascript" src="./scripts/jquery.min.js">\x3C/script>')</script>
しかし、あなたのスクリプト用に いくつか のフォールバックを設定し、ロードプロセスを最適化するために使用できるライブラリもあります。
例:
basket.js 今のところ最高の変種だと思う。スクリプトをlocalStorageにキャッシュします。これにより、次回の読み込みが高速化されます。最も簡単な呼び出し:
basket.require({ url: '/path/to/jquery.js' });
これは約束を返します、そしてあなたはエラーで次の呼び出しをするか、成功した場合は依存関係を読み込むことができます。
basket
.require({ url: '/path/to/jquery.js' })
.then(function () {
// Success
}, function (error) {
// There was an error fetching the script
// Try to load jquery from the next cdn
});
RequireJS
requirejs.config({
enforceDefine: true,
paths: {
jquery: [
'//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min',
//If the CDN location fails, load from this location
'js/jquery-2.0.0.min'
]
}
});
//Later
require(['jquery'], function ($) {
});
yepnope
yepnope([{
load: 'http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js',
complete: function () {
if (!window.jQuery) {
yepnope('js/jquery-2.0.0.min.js');
}
}
}]);
ajax.googleapis.com を cdnjs.cloudflare.com に置き換えるもう1つのフォールバック
(function (doc, $)
{
'use strict';
if (typeof $ === 'undefined')
{
var script = doc.querySelector('script[src*="jquery.min.js"]'),
src = script.src.replace('ajax.googleapis.com', 'cdnjs.cloudflare.com');
script.parentNode.removeChild(script);
doc.write('<script src="' + src + '"></script>');
}
})(document, window.jQuery || window.Zepto);
ほとんどすべてのパブリックCDNはかなり信頼性が高くなっています。ただし、ブロックされたGoogleドメインが心配な場合は、代替 jQuery CDN に簡単にフォールバックできます。 ただし、そのような場合は、反対の方法で、他のCDNを優先オプションとして使用し、Google CDNにフォールバックして失敗を回避することをお勧めしますリクエストと待機時間:
<script src="https://pagecdn.io/lib/jquery/3.2.1/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"><\/script>');
</script>