GoogleでホストされているjQueryを使用するのに最適な方法ですが、Googleでホストされているライブラリにフォールバックできません


1016

Google(または他のGoogleがホストするライブラリ)でホストされているjQueryをロードしようとする良い方法は何ですか?Googleの試みが失敗した場合、jQueryのコピーをロードしますか?

Googleが不安定だと言っているのではない。Googleのコピーがブロックされている場合があります(明らかにイランなど)。

タイマーを設定してjQueryオブジェクトをチェックしますか?

両方のコピーが通過する危険性は何ですか?

「Googleのものを使用する」や「自分のものを使用する」などの答えを探しているわけではありません。私はそれらの議論を理解しています。また、ユーザーがGoogleバージョンをキャッシュしている可能性が高いことも理解しています。クラウドのフォールバック全般について考えています。


編集:このパーツが追加されました...

Googleはgoogle.loadを使用してajaxライブラリーをロードすることを推奨しており、完了時にコールバックを実行するので、それがこの問題をシリアル化するための鍵かどうか疑問に思っています。

少しおかしく聞こえます。私はそれが信頼できる方法でできるかどうかを考えているところです。


更新:jQueryがMicrosoftのCDNでホストされるようになりました。

http://www.asp.net/ajax/cdn/


9
もちろん、最初の答えは「Googleがホストするバージョンを使用しないでください」でした。:-)
Nosredna '06 / 06/18

7
もちろん、深刻なWebサイトをホストしたい場合は、ファイルをホストしている他の誰かに頼らないからです。
Bryan Migliorisi、2009年

6
@ブライアン・ミリオーリシ、ツイッターは結局それほど深刻ではないと思いますか?しかし、Googleがダウンした1か月前のように、Googleに問題があったことは認めます。
Ionuț G. Stan

18
JS libホスティングにGoogleを使用するかどうかのメリットは価値がありますが、他のいくつかのスレッドで説明されています。ロード遅延のJSフォールバックに関する技術的な回答を探していました。
Nosredna 09年

2
@Joe Chung:ユーザーのシステムにキャッシュされる可能性が高く、ページの読み込みが高速化されます。帯域幅を節約します。GoogleのCDNを使用します。その他
Nosredna

回答:


810

あなたはこのようにそれを達成することができます:

<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>(ただし、間違いのないわけではありません!)。

GoogleがホストするjQueryを使用しないもう1つの理由は、一部の国ではGoogleのドメイン名が禁止されていることです。


35
JavaScriptはブロッキング(同期)を既にダウンロードしていませんか?したがって、私には二重コピーの問題は問題にならないようです。
マットシャーマン

68
Matt Shermanが言ったように、Javascriptのダウンロードはすでに同期しているはずです。そうしないと、ページが半分だけダウンロードされたライブラリに依存するインラインスクリプトを実行しようとしたり、ライブラリが完全にダウンロードおよび実行されずにライブラリ拡張が実行されたりすると、多くの問題が発生します。これは、Yahoo YSlowがJavaScriptをページの最後に配置することを推奨する理由の1つでもあります。他のページ要素(スタイルや画像を含む)のダウンロードを妨げないようにします。少なくとも、ブラウザは実行を順番に実行するために遅延させる必要があります。
09年

42
バリデータの狂信者からの小さな修正:文字列 '</'は、スクリプトタグ(SGML短いタグ表記)の終わりとして誤って解釈される可能性があるため、JavaScriptでは許可されていません。代わりに '<' + '/ script>'を実行してください。乾杯、
Boldewyn 2009年

8
この例は機能しません。1)Google ajaxライブラリが利用できない場合、失敗する前にまずタイムアウトする必要があります。これは時間がかかる場合があります。コンピュータをネットワークから切断するという私のテストでは、試行錯誤してタイムアウトしませんでした。2)(!jQuery)がエラーをスローする場合jQueryが定義されていないため、JavaScriptはそれをどう処理するかを認識できません。
RedWolves、2009年

32
jQueryがロードされたかどうかをテストするために、(!window.jQuery)は正常に機能し、typeofチェックよりも短くなります。
ジョーンZaefferer

335

これをはるかに簡単かつクリーンに行う方法:

<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>

1
@jppないためXHTML 1.0HTML 4.01
BenjaminRH

5
人々は削除する私を求め続けるtype="text/javascript"あなたは今ではそれを追加する必要がありますことに注意してください、そう古いブラウザのHTMLを書く人に、部品を。
BenjaminRH

6
@BenjaminRH:type="text/javascript"すべてのJavascriptがデフォルトであるため、古いブラウザでも不要でした。本当に古いブラウザはlanguage属性を調べました。それでも、属性が欠落している場合は、JavaScriptがデフォルトでした。
Martijn 2013

1
@Martijnしかし、私は光沢のある検証バッジが好きでした:)
BenjaminRH

3
@Trojan完全に可能です。呼び出しをスタックするだけです。この時点で新しい接続ホストを開いているので、HTTPパイプラインはおそらくより高速になることに注意してください。... <script src="//cdn1.com/jquery.js"></script> <script>window.jQuery || document.write('<script src="//cdn2.com/jquery.js"><\/script>')</script> <script>window.jQuery || document.write('<script src="local/jquery.js"><\/script>')</script>
トムマッケンジー

76

これは私にとってはうまくいくようです:

<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呼び出しがオブジェクトにロードするオブジェクトを使用することです。そのオブジェクトが存在しない場合、Googleへのアクセスが失敗していると想定しています。その場合は、を使用してローカルコピーを読み込みます。(この場合は自分のサーバーを使用しています。これをテストするには自分のサーバーを使用してください)。windowdocument.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ブロックをさまざまなバージョンで使用しようとしましたが、これほどきれいな組み合わせを見つけることができませんでした。純粋に演習として、このアイデアの他の実装を見てみたいと思います。


1
この状況でgoogle.loadを使用する利点は何ですか?それを直接ロードすると、削除されたライブラリの問題もキャッチされます(GoogleがJQuery 1.3.2の提供を停止した場合はどうなりますか)。さらに、www.google.com / jsapiがフェッチされた後、特にjsapiがキャッシュからロードされた後、Ronyのバージョンはネットワークの問題に気づきますか?確実にするためにgoogle.loadコールバックを使用する必要がある場合があります(またはif(..)にgoogle.loadを含めるための戻り値がある場合があります)。
Arjan、

Google.comの存在をテストしている場合、ネットワークコールを行うか、「ゲートキーパー」オブジェクトの存在を確認することができます。私がやっていることはグーグルオブジェクトとその「ロード」機能をチェックすることです。これらの両方が失敗した場合、Googleはありません。ローカルバージョンが必要です。Ronyのバージョンは実際にはwww.google.com/jsapi URLを完全に無視しているので、それがフェッチされることを示す理由がわかりません。
artlung 2009年

最後に、必要なのは、jqueryライブラリがロードされていることだけです。Googleライブラリは必須ではありません。Ronyの答えでは、Google(またはキャッシュ)からのロードが成功したかどうかは確かです。しかし、「if(window.google && window.google.load)」のチェックでは、jqueryライブラリがまだロードされていません。jqueryライブラリの実際のロードは検証されていませんか?
Arjan、

ああ、どうやって混乱を引き起こしたのか分かります。「www.google.com/jsapiが取得された後、Ronyのバージョンはネットワークの問題に気づきます」:「www.google.com/jsapiが取得された後のバージョンはネットワークの問題に気づきません」
Arjan、

2
最近、jQueryホストとしてGoogleを使用するように切り替えました。ブロックされたユーザーからバグレポートを受け取った場合、クライアントコードをリファクタリングするために、あなたの回答のバリアントを使用します。いい答えです!
ジャロッドディクソン

30

サイトにmodernizr.jsが埋め込まれている場合は、組み込みのyepnope.jsを使用して、スクリプトを非同期にロードできます-特にjQuery(フォールバックあり)。

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();
    }
}]);

これにより、jQueryがGoogle-cdnからロードされます。その後、jQueryが正常にロードされたかどうかがチェックされます。そうでない場合( "nope")、ローカルバージョンがロードされます。また、個人用スクリプトがロードされます。「両方」は、ロードプロセスがテストの結果とは関係なく開始されることを示します。

すべてのロードプロセスが完了すると、関数(MyApp.initの場合)が実行されます。

私は個人的に、この方法で非同期スクリプトをロードすることを好みます。そして、私はサイトを構築するときにmodernizrが提供する機能テストに依存しているので、とにかくそれをサイトに埋め込んでいます。したがって、実際にはオーバーヘッドはありません。


2
私はあなたが質問のポイントを逃していると思います-CDNからmoernizrスクリプトをロードするにはどうしますか?
ジョージフィリパコス2013

2
CDNからModernizrを読み込むことはお勧めできません。むしろ、modernizr.comから最小のカスタムビルドを取得する必要があります。
Emanuel Kluge 14年

2
したがって、このオプションは+16を取得しますが、他のオプションは500/200 +を取得しています。しかし、これはかなりいいですね。Modernizerに依存しているため、人気がないのですか?とにかく私たちのサイトでModernizerを使用しているので、これが他の回答よりも優れている場合は、誰かに知らせてもらえますか?私はJQueryにかなり新しいので、説明はありがたいです。
redfox05 2014年

2
これは回答の時点では本当に良いオプションでしたが、2015年の時点yepnope.jsで非推奨になりました。stackoverflow.com/questions/33986561/…を
Obmerk Kronen 2017

Modernizrは、この質問のような問題を解決するために作成されました。1
カルロス・クイジャーノ

21

ここにはいくつかの優れた解決策がありますが、ローカルファイルに関しては、さらに一歩進めたいと思います。

Googleが失敗するシナリオでは、ローカルソースをロードする必要がありますが、サーバー上の物理ファイルが必ずしも最良のオプションであるとは限りません。現在同じソリューションを実装しているため、これを取り上げますが、データソースによって生成されるローカルファイルにフォールバックしたいだけです。

これの私の理由は、Googleからロードしたものとローカルサーバー上にあるものを追跡することに関して心に留めたいということです。バージョンを変更したい場合は、ローカルコピーをGoogleからロードしようとしているものと同期させておきます。多くの開発者がいる環境では、このプロセスを自動化して、構成ファイルのバージョン番号を変更するだけで済むようにするのが最善の方法だと思います。

理論的に機能するはずの私の提案するソリューションは次のとおりです。

  • アプリケーション構成ファイルには、ライブラリの絶対URL、JavaScript APIのURL、バージョン番号の3つを保存します。
  • ライブラリ自体のファイルコンテンツを取得するクラスを記述し(アプリ構成からURLを取得)、名前とバージョン番号を使用してデータソースに保存します
  • ローカルファイルをデータベースから引き出し、バージョン番号が変更されるまでファイルをキャッシュするハンドラーを記述します。
  • それが(私のアプリ構成で)変更された場合、クラスはバージョン番号に基づいてファイルの内容をプルし、データソースに新しいレコードとして保存します。その後、ハンドラーが起動して新しいバージョンを提供します。

理論的には、私のコードが適切に記述されている場合、私がする必要があるのは、アプリの構成のバージョン番号を変更することだけです。自動化されたフォールバックソリューションがあり、サーバー上の物理ファイルを維持する必要はありません。

みんなどう思いますか?多分これはやり過ぎかもしれませんが、それはあなたのAJAXライブラリを維持するためのエレガントな方法であるかもしれません。

どんぐり


jQueryのためだけにすべての作業を行っている場合、それはやり過ぎです。ただし、アプリの他の部分のためにこれらのコンポーネントのいくつかがすでに配置されている場合(たとえば、DBから既にスクリプトをロードしている場合)は、見栄えがとても良いです。
Michael Haren

1
徹底的で斬新であることの+1。ただし、その利点は開発時間と複雑さを正当化するとは確信していません。
Cory House

20
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>');

2
+1のほうがきれいに見えます。上部にマイナータイプミスがあり、 'undefined'の後の
非常に

1
最初のオプションはChromeの警告を回避します[Violation] Avoid using document.write().
ボブスタイン

残念ながら、最初のオプションは同期して読み込まれないようです。2番目のオプションはありません
ボブスタイン

10

最後の手段としてローカルファイルを使用することもできます。

現在のところ、jQuery自体のCDNはhttpsをサポートしていません。もしそうなら、最初にそこからロードしたいと思うかもしれません。

シーケンスは次のとおりです:Google CDN => 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> 

本当に複数のフォールバックが必要ですか?両方がオフラインの場合、ユーザーは1分以上待ってからサイトを表示します
George Filippakos 2013

1
スクリプトの読み込みに失敗するのに1分はかかりません。
Edward Olamisan 2013

@ geo1701とエドワード、3分の1は本当に必要ありません。フォールバックが1つであっても、信頼性がまだ証明されていません。Google APIがダウンしている場合、最初の試行が失敗するという保証はまだありません。:ここに述べたように、私は、今までのレンダリングからページを保持し、CDNは、負荷に失敗したことがない場合のシナリオを経験したstevesouders.com/blog/2013/03/18/http-archive-jquery/...
hexalys

6

最新/レガシー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]-->

これはクロスブラウザ互換ではありません。
Josh Habdas 2017年

ジョシュ、そうです。
ネイカー2017年



4

これは素晴らしい説明です!

ロードの遅延とタイムアウトも実装します!

http://happyworm.com/blog/2010/01/28/a-simple-and-robust-cdn-failover-for-jquery-14-in-one-line/


リンクのみの回答は役に立たず、低品質と見なされます。もちろんソースへの帰属とともに、関連するビットを回答にコピーすることを検討してください。
random_user_name

@cale_b冗談ですか?この回答は7年以上前のものなので、そのようなコメントは不当です。
Stuart.Sklinar

ええ、それは古い答えです。彼らの提案は有効ですが。他の場所への単なるリンクである回答は削除の候補です。さらなる読者:meta.stackoverflow.com/q/8259
Rob

私は完全に同意します、私は提案を自分でモデレートします-しかし、それは7年後にそれを言っても意味がありません。それは7年後ではなく7年前にそのように緩和されるべきだった。
Stuart.Sklinar

1
@ Stuart.Sklinar-7年前にそれを見ていたとしたら、:)私はここでいくつかの研究をしていて、これを初めて見ました。ご
不便をおかけして

4

ASP.NET MVC 5を使用している人のために、BundleConfig.csに次のコードを追加して、jqueryのCDNを有効にします。

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);

4

更新:
この答えは間違っていることが判明しました。実際の説明についてはコメントをご覧ください。


あなたの質問のほとんどは答えられていますが、最後の部分については:

両方のコピーが通過する危険性は何ですか?

本当にありません。帯域幅を浪費し、数ミリ秒追加して2番目の役に立たないコピーをダウンロードする可能性がありますが、両方が通過しても実際には害はありません。もちろん、上記の手法を使用してこれを回避する必要があります。


5
この質問によると、実際には、jQueryを2回ロードすると、多くの問題が発生する可能性があります。
ShadowCat7 2013

自分でテストして、jqueryライブラリを手動で2回ロードしてみませんか。その後、答えが明らかにされます。
luke_mclachlan

なぜそんなに間違っているのですか?@ ShadowCat7は、それが引き起こす問題についてより具体的に説明できますか?リンクした質問で明確に識別された唯一の問題は、「以前にロードされたすべてのプラグインをクリアする」ことです。しかし、同じjQueryファイルを2回続けてロードする場合は、これは当てはまりません。ここでのローカルフォールバックに対する他のソリューションは非常に複雑であり、document.writeはいくつかの場所でとして悪用されているのでお願いします。
ボブスタイン

2

jQueryがまだロードされていない場合は動的にロードするGistを作成しました。ソースが失敗した場合は、フォールバックに進みます(多くの回答からつなぎ合わされます):https : //gist.github.com/tigerhawkvok/9673154

Gistは常に更新するつもりですが、この答えは更新しないことに注意してください。

/* 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();
}

2

GoogleがホストするjQuery

  • 古いブラウザ、主にIE9より前のバージョンのIEに関心がある場合、これは最も広く互換性のあるjQueryバージョンです
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  • oldIEを気にしない場合、これは小さくて高速です。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

バックアップ/フォールバック計画!

  • どちらの方法でも、Google CDNに障害が発生する(可能性が低い)か、ユーザーが(やや可能性が高い)イランや中国などのサイトからアクセスする場所でブロックされる場合に備えて、ローカルへのフォールバックを使用する必要があります。
<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


安全でないプロトコルでスクリプトをロードすると、XSS攻撃ベクトルが開かれることに注意してください。
Josh Habdas 2017年

2

文字列の最後の<を\ 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>

2
if (typeof jQuery == 'undefined')) { ...

または

if(!window.jQuery){

cdnバージョンがロードされていない場合は動作しません。ブラウザがこの状態を実行し、その間にjQueryを必要とする残りのJavaScriptをダウンロードしてエラーを返すためです。解決策は、その条件でスクリプトをロードすることでした。

    <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>

Google Chromeでのスクリプトのテストで1つの問題-キャッシュが見つかりました。そのため、ローカルテストの場合は、elseセクションのsrcをs.src = 'my_javascripts.js' + '?' + Math.floor(Math.random()* 10001);のように置き換えます。
MirekKomárek、2011

cdnバージョンがロードされていない場合、Alexの答えは機能しません。ブラウザがこの状態を実行し、その間にjqueryを必要とする残りのJavaScriptをダウンロードし、エラーを返します ->ダウンロード中のJavaScriptファイルにより、次のコードの実行がブロックされますだから問題ではありません
アレックス、

2

ほとんどすべてのパブリック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>

1

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")

私はレイザーについて心を決してしましたが、それはそれは(それは限り倍のコードが長いというよりも短くなりますことを除いて、難読化のように見えるこの
maaartinus

@maaartinus:それはリンゴ同士の比較ではありません。あなたが参照するBenjaminRHの答えは、単一のCDNがホストするスクリプトに対するものです。ではCdnScriptヘルパー、あなたは、コードの一行だけ必要なスクリプトあたりを。スクリプトが多いほど、見返りも大きくなります。
エドワードブレイ2014年

確かに...それはただの怒りだった。しかし、それは最適な方法ではないと思います。何かが失敗した場合は、CDNを完全に無視して、すべてのスクリプトのフォールバックに切り替えます。ロードが正確にどのように機能するのかわからないので、これが実行可能かどうかはわかりません。
maaartinus 2014年

@maaartinus:各CDNスクリプトのロードは個別に失敗する可能性があるため、各ロードを個別に確認する必要があります。ローカルでCDNからすべてのスクリプトをロードする単一のCDNチェックの信頼できる方法はありません。
エドワードブレイ2014年

私が心配しているのは、CDNサイトの障害であり、多くのロードの待機時間が発生しています。だから私はのようなものが欲しいですtry { for (Script s : ...) cdnLoad(s); } catch (...) { for (Script s : ...) ownLoad(s); }。これをifsの束に変換するのは悪夢かもしれません。
maaartinus 2014年

1

document.write("<script></script>")jQueryバックオフの方が書き込みは簡単に思えますが、その場合、Chromeでは検証エラーが発生します。だから私は「スクリプト」の単語を壊すことを好む。したがって、上記のように安全になります。

<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リクエストにはバニラ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>


0

ajax.googleapis.comcdnjs.cloudflare.comで置き換えるさらに別のフォールバック:

(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);
  • 文字列で指定することにより、jQueryバージョンに固執できます
  • HTMLスニップでは機能しないアセット管理に最適
  • 野生でテスト済み-中国のユーザーに最適な作品

「jQueryのバージョンを気にする必要はありません」というステートメントについて詳しく教えてください。
Josh Habdas 2017年

このバージョンは、このアプローチに触れてはいけないURLの一部です... jquery / 3.xx / jquery.min.js
redaxmedia '18

1
jQueryがバージョン4に改訂し、下位互換性のない変更が導入された場合、破損する可能性がありますか?
Josh Habdas 2017

-1は、バージョンが指定されていない限り、jQueryがスクリプトでまだサポートしていない重大な変更を導入すると、破損を引き起こすためです。
Lookaji 2018

@lookajiあなたはフォールバックを理解していないと思います。ホストされているドメインを置き換え、ファイル名やバージョンには一切触れません。
redaxmedia 2018

0

次のようなコードを使用できます。

<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
  • RequireJS
  • イェノペ

例:

basket.js 私は今のところ最良のバリアントだと思います。スクリプトをlocalStorageにキャッシュし、次の読み込みを高速化します。最も簡単な呼び出し:

basket.require({ url: '/path/to/jquery.js' });

これによりpromiseが返され、エラー時に次の呼び出しを行うか、成功時に依存関係をロードできます。

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([{
  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');
    }
  }
}]);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.