Nice programing

Google의 호스팅 된 jQuery를 사용하는 가장 좋은 방법이지만 Google의 호스팅 된 라이브러리로 대체 실패

nicepro 2020. 9. 27. 13:59
반응형

Google의 호스팅 된 jQuery를 사용하는 가장 좋은 방법이지만 Google의 호스팅 된 라이브러리로 대체 실패


Google (또는 다른 Google 호스팅 라이브러리) 에서 호스팅 된 jQuery 를로드하려고 시도 하지만 Google 시도가 실패하면 내 jQuery 사본 을로드하는 좋은 방법은 무엇입니까 ?

나는 구글이 불안정하다는 말이 아니다. Google 카피가 차단되는 경우가 있습니다 (예를 들어이란에서 분명히 나타남).

타이머를 설정하고 jQuery 객체를 확인합니까?

두 복사본이 모두 들어오는 위험은 무엇입니까?

"Google을 사용하십시오"또는 "자신의 것을 사용하십시오"와 같은 답변을 찾지 않습니다. 나는 그 주장을 이해합니다. 또한 사용자가 Google 버전을 캐시 할 가능성이 있음을 이해합니다. 일반적으로 클라우드에 대한 폴백에 대해 생각하고 있습니다.


편집 :이 부분이 추가되었습니다 ...

Google은 google.load를 사용하여 ajax 라이브러리를로드 할 것을 제안하고 완료되면 콜백을 수행하므로 이것이이 문제를 직렬화하는 열쇠인지 궁금합니다.

나는 그것이 약간 미친 소리라는 것을 압니다. 믿을 수있는 방법으로 할 수 있는지 아닌지 알아 내려고하는 것뿐입니다.


업데이트 : 이제 jQuery가 Microsoft의 CDN에서 호스팅됩니다.

http://www.asp.net/ajax/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>오류를 방지하기 위해 에 있어야합니다 (완벽한 것은 아니지만!).

Google에서 호스팅하는 jQuery를 사용 하지 않는 또 다른 이유 는 일부 국가에서 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/jsapigoogle 를 호출 하여 객체에 로드되는 객체 를 사용하는 것입니다 . 해당 개체가 없으면 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 블록을 사용하려고 시도했지만 이것만큼 깨끗한 조합을 찾을 수 없었습니다. 이 아이디어의 다른 구현을 순전히 연습으로보고 싶습니다.


사이트에 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") 로컬 버전이로드됩니다. 또한 개인 스크립트가로드됩니다. "둘 다"는로드 프로세스가 테스트 결과와 독립적으로 시작됨을 나타냅니다.

모든로드 프로세스가 완료되면 'MyApp.init'의 경우 함수가 실행됩니다.

개인적으로이 비동기 스크립트 로딩 방식을 선호합니다. 그리고 사이트를 구축 할 때 modernizr에서 제공하는 기능 테스트에 의존하기 때문에 어쨌든 사이트에 삽입했습니다. 따라서 실제로 오버 헤드가 없습니다.


여기에는 몇 가지 훌륭한 솔루션이 있지만 로컬 파일과 관련하여 한 단계 더 나아가고 싶습니다.

Google이 실패하는 시나리오에서 로컬 소스를로드해야하지만 서버의 실제 파일이 반드시 최선의 선택이 아닐 수도 있습니다. 현재 동일한 솔루션을 구현하고 있기 때문에이 문제를 제기하지만 데이터 소스에서 생성 된 로컬 파일로 대체하고 싶습니다.

그 이유는 내가 Google에서로드하는 것과 로컬 서버에있는 것을 추적 할 때 마음의 일부를 갖고 싶기 때문입니다. 버전을 변경하려면 로컬 사본을 Google에서로드하려는 것과 동기화하고 싶습니다. 개발자가 많은 환경에서 가장 좋은 방법은이 프로세스를 자동화하여 구성 파일의 버전 번호를 변경하는 것 뿐이라고 생각합니다.

이론적으로 작동해야하는 제안 된 솔루션은 다음과 같습니다.

  • 애플리케이션 구성 파일에는 라이브러리의 절대 URL, JavaScript API의 URL, 버전 번호의 세 가지를 저장합니다.
  • 라이브러리 자체의 파일 내용을 가져 오는 클래스를 작성하고 (앱 구성에서 URL 가져 오기) 이름과 버전 번호로 내 데이터 소스에 저장합니다.
  • 내 로컬 파일을 db에서 가져오고 버전 번호가 변경 될 때까지 파일을 캐시하는 핸들러를 작성하십시오.
  • 변경되면 (내 앱 구성에서) 내 클래스는 버전 번호를 기반으로 파일 콘텐츠를 가져 와서 내 데이터 소스에 새 레코드로 저장 한 다음 핸들러가 시작되어 새 버전을 제공합니다.

이론적으로 내 코드가 제대로 작성 되었다면 내 앱 구성에서 버전 번호를 변경 한 다음 비올라를 변경하면됩니다! 자동화 된 대체 솔루션이 있으며 서버에서 실제 파일을 유지할 필요가 없습니다.

다들 어떻게 생각하세요? 이것은 과잉 일 수도 있지만 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를 지원하지 않는 것 같습니다. 그렇다면 먼저 거기에서로드 할 수 있습니다.

순서는 다음과 같습니다. 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> 

최신 / 레거시 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]-->

  • 1 단계 : jQuery가로드되지 않았습니까? ( jQuery변수 확인 )

JavaScript에서 정의되지 않은 변수를 확인하는 방법

  • 2 단계 : 동적으로 가져 오기 (백업) 자바 스크립트 파일

다른 JavaScript 파일에 JavaScript 파일을 어떻게 포함합니까?


Google의 금지 문제 때문에 Microsoft의 cdn http://www.asp.net/ajaxlibrary/cdn.ashx 를 사용하는 것을 선호합니다 .


이것에 대한 훌륭한 설명이 있습니다!

또한 로딩 지연 및 시간 초과를 구현합니다!

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


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

업데이트 :
이 대답은 잘못된 것으로 판명되었습니다. 실제 설명은 코멘트를 참조하십시오.


대부분의 질문에 대한 답변이 있지만 마지막 부분은 다음과 같습니다.

두 복사본이 모두 들어오는 위험은 무엇입니까?

정말 없습니다. 대역폭을 낭비하고 쓸모없는 두 번째 사본을 다운로드하는 데 몇 밀리 초를 추가 할 수 있지만 둘 다 통과하더라도 실제 피해는 없습니다. 물론 위에서 언급 한 기술을 사용하여이를 피해야합니다.


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

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


나는 그것이 문자열에서 마지막 <에서 \ 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>

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

또는

if(!window.jQuery){

브라우저가이 조건을 통해 실행되고 jQuery가 필요한 나머지 자바 스크립트를 계속 다운로드하고 오류를 반환하기 때문에 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>

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

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>

For long term issues, it would be better to log JQuery fallbacks. In the code above, if first CDN is not available JQuery is loaded from another CDN. But you could want to know that erroneous CDN and remove it permanently. (this case is very exceptional case) Also it is better to log fallback issues. So you can send erroneous cases with AJAX. Because of JQuery isn't defined, you should use vanilla javascript for AJAX request.

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

The inability to load the resource from an external data store beyond your control is difficult. Looking for missing functions is totally fallacious as a means to avoid suffering a timeout, as described herein: http://www.tech-101.com/support/topic/4499-issues-using-a-cdn/


Almost all public CDNs are pretty reliably. However, if you are worried about blocked google domain, then you can simply fallback to an alternative jQuery CDN. However, in such a case, you may prefer to do it opposite way and use some other CDN as your preferred option and fallback to Google CDN to avoid failed requests and waiting time:

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

Yet another fallback that replaces ajax.googleapis.com with 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);
  • You can stick to a jQuery version by specifying it in the string
  • Perfect for Asset Management that doesn't work with HTML snips
  • Tested in the wild - works perfect for users from China

You can use code like:

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

But also there are libraries you can use to setup several possible fallbacks for your scripts and optimize the loading process:

  • basket.js
  • RequireJS
  • yepnope

Examples:

basket.js I think the best variant for now. Will cach your script in the localStorage, that will speed up next loadings. The simplest call:

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

This will return a promise and you can do next call on error, or load dependencies on success:

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

참고URL : https://stackoverflow.com/questions/1014203/best-way-to-use-googles-hosted-jquery-but-fall-back-to-my-hosted-library-on-go

반응형