web-dev-qa-db-ja.com

GoogleのホステッドjQueryを使用する最良の方法ですが、Googleのホステッドライブラリにフォールバックすると失敗します

GoogleでホストされているjQuery (または他のGoogleがホストされているライブラリ)をロードしようとすると、どうしたらよいでしょうか。

グーグルがフレークだと言っているのではない。 Googleのコピーがブロックされている場合があります(たとえば、イランなど)。

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

両方のコピーが届く危険性は何でしょうか。

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


編集:この部分を追加しました...

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

ちょっとクレイジーに聞こえますね。信頼できる方法でできるかどうかを判断しようとしているだけです。


更新:jQueryは現在MicrosoftのCDNでホストされています。

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

1002
Nosredna

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

<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のドメイン名が禁止されているためです。

794
Rony

これを行う最も簡単でわかりやすい方法:

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

これは私のために働くようです:

<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ブロックを使用しようとしましたが、これほどきれいな組み合わせを見つけることができませんでした。他の実装も見たいです。純粋に練習として、このアイデアの。

75
artlung

あなたのサイトに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が提供する機能テストに頼っているので、とにかくサイトに埋め込んでいます。そのため、実際にはオーバーヘッドはありません。

30
Emanuel Kluge

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

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

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

これが私の提案した解決策で、理論上はうまくいくはずです。

  • アプリケーション構成ファイルには、ライブラリの絶対URL、JavaScript APIのURL、およびバージョン番号の3つを格納します。
  • ライブラリ自体のファイルの内容を取得する(app configからURLを取得する)クラスを作成し、それを名前とバージョン番号とともに私のデータソースに格納します。
  • ローカルファイルをdbから取り出してバージョン番号が変わるまでファイルをキャッシュするハンドラを作成します。
  • それが変更された場合(私のアプリの設定で)、私のクラスはバージョン番号に基づいてファイルの内容を取得し、それを私のデータソースの新しいレコードとして保存します。

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

みんなはどう思いますか?これはやり過ぎるかもしれませんが、AJAXライブラリを管理する上品な方法になるかもしれません。

どんぐり

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

ローカルファイルを最後の手段として使用することをお勧めします。

今のところ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> 
9
Edward Olamisan

最新/従来の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]-->
6
neiker

グーグルの禁止問題のために、私はマイクロソフトのcdn http://www.asp.net/ajaxlibrary/cdn.ashx を使うのを好む。

5
Serdar
  • ステップ1:jQueryが読み込めませんでしたか? (jQuery変数を確認してください)

JavaScriptで未定義の変数をチェックする方法

  • ステップ2:(バックアップの)javascriptファイルを動的にインポートする

JavaScriptファイルを別のJavaScriptファイルに含める方法

5
ninjagecko

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番目の無駄なコピーをダウンロードするのに数ミリ秒を追加するかもしれませんが、それらが両方とも通過するなら実際の害はありません。もちろん、上記のテクニックを使ってこれを避けるべきです。

4
WhyNotHugo

これはこれについてのすばらしい説明です。

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

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

4
Stuart.Sklinar

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();
}
2
Philip Kahn

文字列の最後の<から\ 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
JKhuang

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

2
Ryan
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>
2
Mirek Komárek

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

あなたの制御を超えて外部データストアからリソースをロードできないことは困難です。欠落している機能を探すことは、ここで説明されているように、タイムアウトの発生を回避する手段として完全に間違っています: http://www.tech-101.com/support/topic/4499-issues-using-a-cdn/

1
jobeard

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")
1
Edward Brey

次のようなコードを使うことができます。

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

これは約束を返します、そしてあなたはエラーで次の呼び出しをするか、成功した場合は依存関係を読み込むことができます。

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);
  • 文字列で指定することでjQueryのバージョンに固執することができます
  • HTMLスニップでは機能しないAsset Managementに最適
  • 実際にテスト済み - 中国のユーザーに最適
0
redaxmedia

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