it-swarm.com.ru

Лучший способ использовать размещенный в Google jQuery, но вернуться к моей размещенной в Google библиотеке не удалось

Как можно было бы попытаться загрузить размещенный jQuery в Google (или другие размещенные в Google библиотеки), но загрузить мою копию jQuery, если попытка Google не удалась?

Я не говорю, что Google ненадежен. В некоторых случаях копия Google блокируется (например, в Иране).

Я установил бы таймер и проверил бы для объекта jQuery?

Какова будет опасность того, что обе копии будут получены?

На самом деле не нужно искать ответы типа «просто воспользуйтесь Google» или «просто используйте свой». Я понимаю эти аргументы. Я также понимаю, что пользователь, скорее всего, будет кэшировать версию Google. Я имею в виду запасные варианты для облака в целом.


Правка: эта часть добавлена ​​...

Так как Google предлагает использовать google.load для загрузки библиотек ajax, и он выполняет обратный вызов после завершения, я задаюсь вопросом, является ли это ключом к сериализации этой проблемы.

Я знаю, это звучит немного безумно. Я просто пытаюсь понять, можно ли это сделать надежным способом или нет.


Обновление: jQuery теперь размещен на CDN от Microsoft.

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

1001
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>, чтобы избежать ошибок (хотя это не защищает от ошибок!).

Еще одна причина нет использования Google jQuery - это то, что в некоторых странах доменное имя Google запрещено.

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

Как это работает, это использовать объект google, который вызывает http://www.google.com/jsapi загружает в объект 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 API библиотек .

Интересный факт: Сначала я пытался использовать для этого блок try..catch в разных версиях, но не смог найти такую ​​же чистую комбинацию. Мне было бы интересно увидеть другие реализации этого идея, чисто как упражнение.

75
artlung

Если на вашем сайте встроен 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 успешно загружен. Если нет («нет»), загружается локальная версия. Также загружаются ваши личные скрипты - «оба» указывают, что процесс загрузки инициируется независимо от результата теста.

Когда все процессы загрузки завершены, выполняется функция, в случае «MyApp.init».

Я лично предпочитаю этот способ асинхронной загрузки скрипта. И так как я полагаюсь на функциональные тесты, предоставляемые modernizr при создании сайта, я все равно встроил его в сайт. Так что на самом деле нет накладных расходов.

30
Emanuel Kluge

Здесь есть несколько отличных решений, но я хотел бы сделать еще один шаг в отношении локального файла.

В случае, когда Google терпит неудачу, он должен загрузить локальный источник, но, возможно, физический файл на сервере не обязательно является лучшим вариантом. Я поднял этот вопрос, потому что в настоящее время я реализую то же решение, только я хочу вернуться к локальному файлу, который генерируется источником данных.

Мои причины в том, что я хочу иметь некоторый разум, когда дело доходит до отслеживания того, что я загружаю из Google, и того, что у меня есть на локальном сервере. Если я хочу изменить версии, я хочу, чтобы моя локальная копия синхронизировалась с тем, что я пытаюсь загрузить из Google. В среде, где есть много разработчиков, я думаю, что лучшим подходом было бы автоматизировать этот процесс так, чтобы все, что нужно было сделать, это изменить номер версии в файле конфигурации.

Вот мое предлагаемое решение, которое должно работать в теории:

  • В файле конфигурации приложения я буду хранить 3 вещи: абсолютный URL-адрес для библиотеки, URL-адрес для JavaScript API и номер версии
  • Напишите класс, который получает содержимое файла самой библиотеки (получает URL из конфигурации приложения), сохраняет его в моем источнике данных с именем и номером версии.
  • Напишите обработчик, который извлекает мой локальный файл из базы данных и кэширует файл до тех пор, пока не изменится номер версии.
  • Если это изменится (в моем конфиге приложения), мой класс извлечет содержимое файла на основе номера версии, сохранит его как новую запись в моем источнике данных, затем обработчик включит и предоставит новую версию.

Теоретически, если мой код написан правильно, все, что мне нужно сделать, это изменить номер версии в конфигурации моего приложения, а затем Viola! У вас есть запасное решение, которое автоматизировано, и вам не нужно хранить физические файлы на вашем сервере.

Что все думают? Возможно, это излишне, но это может быть элегантный способ поддержки ваших библиотек 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);

}

После того, как вы попытаетесь включить копию Google из CDN.

В HTML5 вам не нужно устанавливать атрибут type.

Вы также можете использовать ...

window.jQuery || document.write('<script src="/libs/jquery.js"><\/script>');
20
alex

Возможно, вы захотите использовать свой локальный файл в качестве последнего средства.

Похоже, что в настоящее время собственный CDN jQuery не поддерживает 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> 
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

Из-за проблемы запрета Google я предпочитаю использовать cdn http://www.asp.net/ajaxlibrary/cdn.ashx

5
Serdar
  • Шаг 1. Не удалось загрузить jQuery? (проверьте переменную jQuery)

Как проверить неопределенную переменную в JavaScript

  • Шаг 2. Динамический импорт (резервное копирование) файла javascript

Как включить файл JavaScript в другой файл JavaScript?

5
ninjagecko

Для тех, кто использует ASP.NET MVC 5, добавьте этот код в ваш BundleConfig.cs, чтобы включить CDN для jquery:

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
Muhammad Rehan Saeed

Обновление:
Этот ответ оказался неверным. Пожалуйста, смотрите комментарии для реального объяснения.


Большинство из вас ответили на вопрос, но что касается заключительной части:

Какова будет опасность того, что обе копии будут получены?

Ни один на самом деле. Вы бы потратили пропускную способность, могли бы добавить несколько миллисекунд, загружая вторую бесполезную копию, но это не повредит, если они оба пройдут. Вы должны, конечно, избегать этого, используя методы, упомянутые выше.

4
WhyNotHugo

Вот отличное объяснение этого!

Также реализует задержки загрузки и тайм-ауты!

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

4
Stuart.Sklinar

Я сделал Gist, который должен динамически загружать jQuery, если он еще не загружен, и если источник не работает, он переходит к запасным вариантам (сшитым из множества ответов): 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
Philip Kahn

Я считаю, что должен экранировать последний <to\x3C в строке. Когда браузер видит, он считает, что это конец блока скрипта (поскольку анализатор HTML не имеет представления о JavaScript, он не может отличить то, что просто появляется в строке, и то, что фактически предназначено для завершения скрипта. элемент). Поэтому появление буквально в JavaScript, который находится внутри HTML-страницы, (в лучшем случае) вызовет ошибки и (в худшем случае) станет огромной дырой в безопасности.

<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

  • Если вы заботитесь о старых браузерах, в первую очередь о версиях IE до IE9, это наиболее широко совместимая версия 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){

Не будет работать, если версия cdn не загружена, потому что браузер будет проходить через это условие и во время него все еще загружать остальные javascripts, которым требуется jQuery, и он возвращает ошибку. Решением было загрузить сценарии через это условие.

    <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

Хотя написание document.write("<script></script>") кажется более легким для отката jQuery, Chrome выдает ошибку проверки в этом случае. Поэтому я предпочитаю нарушать «сценарий» 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 не определен, вы должны использовать Vanilla Javascript для запроса AJAX.

<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

Используя синтаксис Razor в ASP.NET, этот код обеспечивает резервную поддержку и работает с виртуальным корнем:

@{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
  • yepnope

Примеры:

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([{
  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');
    }
  }
}]);
0
Роман Коптев

Еще один запасной вариант, который заменяет ajax.googleapis.com на cdnjs.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
  • Протестировано в дикой природе - отлично работает для пользователей из Китая
0
redaxmedia