Google의 호스팅 jQuery를 사용하는 가장 좋은 방법이지만 Google의 호스팅 라이브러리로 폴백


1016

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

나는 구글이 비정상적이라고 말하는 것이 아니다. Google 사본이 차단 된 경우가 있습니다 (예 :이란 등).

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

두 사본이 모두 나올 위험은 무엇입니까?

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


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

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

나는 그것이 약간 미친 소리라는 것을 알고 있습니다. 나는 그것이 신뢰할 수있는 방법으로 수행 될 수 있는지 알아 내려고 노력하고 있습니다.


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

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


9
물론 첫 번째 대답은 "Google 호스팅 버전을 사용하지 마십시오"였습니다. :-)
Nosredna 2016 년

7
물론 심각한 웹 사이트를 호스팅하려는 경우 파일을 호스팅하는 다른 사람에게 의존하지 않기 때문입니다.
Bryan Migliorisi 2016 년

6
@ Brian Migliorisi, 트위터가 그렇게 심각하지 않은 것 같아요? 그러나 한 달 전 구글이 다운 된 것처럼 구글에 문제가 있다는 것을 인정한다.
Ionuț G. Stan

18
JS lib 호스팅에 Google을 사용하거나 사용하지 않는 장점은 가치가 있지만 다른 여러 스레드에서 논의되었습니다. 로딩 지연에 대한 JS 대체에 대한 기술적 답변을 찾고있었습니다.
Nosredna 2016 년

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를 사용 하지 않는 또 다른 이유 는 일부 국가에서는 Google의 도메인 이름이 금지되어 있기 때문입니다.


35
자바 스크립트 다운로드 차단 (동기식)이 아닙니까? 따라서 이중 복사 문제는 문제가되지 않는 것 같습니다.
Matt Sherman

68
Matt Sherman이 말했듯이 자바 스크립트 다운로드는 이미 동기화되어 있어야합니다. 그렇지 않으면 페이지가 절반 만 다운로드 된 라이브러리에 의존하는 인라인 스크립트를 실행하려고하거나 라이브러리가 완전히 다운로드 및 실행되지 않은 상태에서 라이브러리 확장이 실행 된 경우 많은 문제가 발생합니다. Yahoo YSlow가 페이지 끝에 자바 스크립트를 다시 설치하도록 권장하는 이유이기도합니다. 다른 페이지 요소 (스타일 및 이미지 포함)의 다운로드를 차단하지 않습니다. 최소한 브라우저는 실행이 지연되어 순차적으로 발생해야합니다.
gapple

42
유효성 검사기의 광신자에 의한 작은 수정 : 문자열 '</'는 스크립트 태그의 끝으로 잘못 해석 될 수 있으므로 JavaScript에서는 허용되지 않습니다 (SGML 짧은 태그 표기법). 대신 '<'+ '/ script>'를 수행하십시오. 건배
Boldewyn

8
이 예제는 작동하지 않습니다. 1) Google ajax 라이브러리를 사용할 수없는 경우 실패하기 전에 먼저 시간 초과해야합니다. 시간이 걸릴 수 있습니다. 컴퓨터를 네트워크에서 분리하는 테스트에서 방금 시도하고 시도하고 시간 초과하지 않았습니다. 2) jQuery가 정의되어 있지 않기 때문에 (! jQuery)가 오류를 throw하면 Javascript는 어떻게 해야할지 알 수 없습니다.
RedWolves 2016 년

32
jQuery가로드되었는지 테스트하려면 (! window.jQuery)가 제대로 작동하고 검사 유형이 짧습니다.
Jörn 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 not XHTML 1.0andHTML 4.01
BenjaminRH

5
사람들은 계속해서 나에게 type="text/javascript"부품 을 제거하라고 요구 하므로 구식 브라우저를 위해 html을 작성하는 사람들에게이를 추가해야합니다.
BenjaminRH

6
@ BenjaminRH : type="text/javascript"이전 브라우저에서도 모두 기본적으로 Javascript이므로 불필요했습니다. 아주 오래된 브라우저는 language속성을 보았습니다 . 그러나 속성이없는 경우 Javascript가 기본값이었습니다.
Martijn

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

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/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 라이브러리 API 를 전혀 사용 하고 있는지 확실하지 않습니다 .

재미있는 사실 : 처음에는 다양한 버전에서 try..catch 블록을 사용하려고 시도했지만 이와 같이 깨끗한 조합을 찾을 수 없었습니다. 이 아이디어의 다른 구현을 순전히 연습으로보고 싶습니다.


1
Rony가 제안한 것처럼 ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js를 직접로드하는 대신이 상황에서 google.load를 사용하면 어떤 이점이 있습니까? 직접로드하면 제거 된 라이브러리 문제가 발생합니다 (Google이 JQuery 1.3.2 제공을 중단하면 어떻게 될까요). 또한 Rony의 버전은 특히 jsapi가 캐시에서로드 된 경우 www.google.com/jsapi를 가져온 후 네트워크 문제를 발견 했습니까? 확실하게하기 위해 google.load 콜백을 사용해야 할 수도 있습니다 (또는 if (..)에 google.load를 포함시키기위한 반환 값이있을 수도 있습니다).
Arjan

Google.com의 존재 여부를 테스트하는 중이라면 네트워크 호출을하거나 "게이트 키퍼"개체가 있는지 확인할 수 있습니다. 내가하고있는 일은 Google 객체와 "로드"기능을 확인하는 것입니다. 두 가지 모두 실패하면 Google이 없으며 로컬 버전이 필요합니다. Rony의 버전은 실제로 www.google.com/jsapi URL을 완전히 무시하므로 URL을 가져 왔음을 나타내는 이유를 잘 모르겠습니다.
artlung 2016 년

결국, 필요한 것은 jquery 라이브러리가로드 된 것입니다. 모든 Google 라이브러리는 필요하지 않습니다. Rony의 대답에 따르면 Google (또는 캐시)에서로드가 성공했는지 확실하게 알 수 있습니다. 그러나 "if (window.google && window.google.load)"를 확인해도 jquery 라이브러리는 여전히로드되지 않습니다. jquery 라이브러리의 실제 로딩이 확인되지 않았습니까?
Arjan

아, 어떻게 내가 혼란을 야기했는지 봅니다. "Rony의 버전은 www.google.com/jsapi를 가져온 후 네트워크 문제를 발견했습니다"는 다음과 같이 잘 읽어야합니다. "버전이 www.google.com/jsapi를 가져온 후 네트워크 문제를 발견하지 못했습니다".
Arjan

2
최근 Google을 jQuery 호스트로 사용하기로 전환했습니다. 차단 된 사용자로부터 버그 보고서를 받으면 고객 코드를 리팩토링하기 위해 다양한 변형을 사용합니다. 좋은 대답입니다!
Jarrod Dixon

30

사이트에 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이 제공하는 기능 테스트에 의존하기 때문에 어쨌든 사이트에 포함되어 있습니다. 따라서 실제로 오버 헤드가 없습니다.


2
나는 당신이 질문의 요점을 놓치고 있다고 생각합니다-CDN에서 moernizr 스크립트를로드하는 방법은 무엇입니까?
George Filippakos

2
CDN에서 Modernizr을로드하는 것을 권장하지 않습니다. modernizr.com에서 가장 작은 사용자 지정 빌드를 가져와야합니다.
Emanuel Kluge

2
따라서이 옵션은 다른 옵션이 얻는 500 / 200 +에 비해 +16을 얻습니다. 그러나 이것은 꽤 좋은 것 같습니다. Modernizer에 의존하여 인기가 있습니까? 어쨌든 우리 사이트에서 Modernizer를 사용하고 있는데 다른 답변보다 낫다면 누군가가 알려 줄 수 있습니까? JQuery에 익숙하지 않으므로 설명이 필요합니다.
redfox05

2
답변 시점에 이것은 정말 좋은 옵션 이었지만 2015 년 기준 yepnope.js으로 더 이상 사용되지 않습니다. 참조 stackoverflow.com/questions/33986561/...
Obmerk 크로 넨

Modernizr 은이 질문과 같은 문제를 해결하기 위해 만들어졌습니다. +1
Carlos Quijano 2016 년

21

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

Google이 실패하는 시나리오에서는 로컬 소스를로드해야하지만 서버의 실제 파일이 최상의 옵션 일 필요는 없습니다. 현재 동일한 솔루션을 구현하고 있기 때문에 이것을 가져옵니다. 데이터 소스로 생성되는 로컬 파일로 폴백하고 싶습니다.

이것에 대한 나의 이유는 내가 구글에서로드하는 것과 로컬 서버에 가지고있는 것을 추적 할 때 약간의 마음을 갖고 싶어하기 때문입니다. 버전을 변경하려면 로컬 사본을 Google에서로드하려는 항목과 동기화 된 상태로 유지하고 싶습니다. 많은 개발자가있는 환경에서 가장 좋은 방법은이 프로세스를 자동화하여 구성 파일의 버전 번호를 변경하는 것입니다.

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

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

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

모두 어떻게 생각하세요? 어쩌면 이것은 과잉이지만 AJAX 라이브러리를 유지 관리하는 우아한 방법 일 수 있습니다.

도토리


jQuery에 대해서만 모든 작업을 수행하는 경우 과잉이라고 말할 수 있습니다. 그러나 앱의 다른 부분을 위해 이미 이러한 구성 요소 중 일부를 가지고 있다면 (예를 들어 이미 DB에서 스크립트를로드하는 경우) 매우 좋습니다.
Michael Haren

1
철저하고 참신한 데 +1하지만, 이점이 개발 시간과 복잡성을 정당화한다고 확신하지는 않습니다.
코리 하우스

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이 더 깨끗해 보입니다. '정의되지 않은'이후에 불완전한 두 개의 닫는 괄호 이후로 명확하지 않은 작은 오타가 있습니다
naveen

1
첫 번째 옵션은 Chrome 경고를 피합니다[Violation] Avoid using document.write().
Bob Stein이

불행히도 첫 번째 옵션은 동 기적 으로로드되지 않는 것 같습니다 . 두 번째 옵션 .
Bob Stein

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

1
스크립트를로드하는 데 1 분이 걸리지 않습니다.
Edward Olamisan

@ geo1701과 Edward, 실제로 3 분의 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 2016 년

조쉬, 그래
neiker 2016 년



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

업데이트 :
이 답변은 잘못된 것으로 판명되었습니다. 실제 설명은 의견을 참조하십시오.


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

두 사본이 모두 나올 위험은 무엇입니까?

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


5
실제로이 질문 에 따르면 jQuery를 두 번로드하면 많은 문제가 발생할 수 있습니다 .
ShadowCat7

왜 직접 테스트하고 jquery 라이브러리를 수동으로 두 번로드하지 않습니까? 그러면 답이 공개 될 것입니다.
luke_mclachlan 2016 년

왜 그렇게 잘못 되었나요? @ ShadowCat7 문제의 원인을 좀 더 구체적으로 설명해 주시겠습니까? 링크 한 질문에서 명시 적으로 식별 된 유일한 문제는 "이전에로드 된 플러그인을 모두 지우는 것"입니다. 그러나 동일한 jQuery 파일을 연속해서 두 번 연속로드하는 데 적용해서는 안됩니다. 나는 지역 대체에 여기에 다른 솔루션이 너무 뒤얽힌 때문에 요청 및 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 2016 년

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

브라우저 가이 조건을 통해 실행되고 여전히 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>

Chrome에서 스크립트를 테스트 할 때 캐싱이라는 한 가지 문제가 발견되었습니다. 따라서 로컬 테스트의 경우 else 섹션의 src를 s.src = 'my_javascripts.js'+ '?'+ Math.floor (Math.random () * 10001)과 같은 것으로 바꾸십시오.
Mirek Komárek 2018

CDn 버전이로드되지 않은 경우 Alex의 답변 이 작동하지 않습니다. 브라우저 가이 조건을 실행하고 jquery가 필요한 나머지 자바 스크립트를 계속 다운로드하는 동안 오류가 발생합니다 -> 다운로드중인 JavaScript 파일은 다음 코드 조각이 실행되지 않도록 차단합니다 그래서 문제가되지 않습니다 .
alex

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도우미를 사용하면 스크립트 당 한 줄의 코드 만 필요합니다 . 스크립트가 많을수록 지불액이 커집니다.
Edward Brey

물론 ... 그것은 단지 진창이었다. 그러나 이것이 최선의 방법은 아니라고 생각합니다. 아무것도 실패하면 CDN을 완전히 무시하고 모든 스크립트의 대체로 전환합니다. 로딩이 정확히 어떻게 작동하는지 모르기 때문에 이것이 가능한지 확실하지 않습니다.
maaartinus

@maaartinus : 각 CDN 스크립트로드는 독립적으로 실패 할 수 있으므로 각로드를 개별적으로 확인해야합니다. 단일 CDN 검사에 대한 신뢰할 수있는 방법은 없으며 CDN과 로컬의 모든 스크립트를로드합니다.
Edward Brey

저를 걱정하는 경우는 CDN 사이트가 실패하여 많은 부하를 기다리는 시간입니다. 그래서와 같은 것을 갖고 싶습니다 try { for (Script s : ...) cdnLoad(s); } catch (...) { for (Script s : ...) ownLoad(s); }. 이것을 여러 무리로 번역하면 if악몽이 될 수 있습니다.
maaartinus

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을 사용할 수 없으면 다른 CDN에서 JQuery가로드됩니다. 그러나 잘못된 CDN을 알고 영구적으로 제거 할 수 있습니다. (이 경우는 매우 예외적입니다) 또한 대체 문제를 기록하는 것이 좋습니다. 따라서 AJAX로 잘못된 사례를 보낼 수 있습니다. JQuery가 정의되지 않았으므로 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

제어 할 수없는 외부 데이터 저장소에서 리소스를로드 할 수없는 것은 어렵습니다. 누락 된 기능을 찾는 것은 여기에 설명 된 것처럼 시간 초과로 고통받지 않도록하는 수단으로 완전히 악의적입니다 .


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

버전은이 접근 방식으로 다루어지지 않는 URL의 일부입니다 ... jquery / 3.xx / jquery.min.js
redaxmedia

1
jQuery가 버전 4로 개정되고 이전 버전과 호환되지 않는 변경 사항이 발생할 때 손상을 일으킬 가능성이 있습니까?
Josh Habdas

jQuery가 버전을 지정하지 않으면 스크립트가 아직 지원하지 않는 주요 변경 사항을 도입하면 중단이 발생하기 때문에 -1입니다.
Lookaji

@lookaji 폴백을 이해하지 못하는 것 같습니다. 호스트 된 도메인을 대체하고 파일 이름 / 버전을 전혀 만지지 마십시오.
redaxmedia

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
  • 요구 JS
  • 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
    });

요구 JS

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');
    }
  }
}]);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.