<Script src = “http: //…”> içinde http: // yerine // koymak geçerli mi?


458

Aşağıdaki öğeye sahibim:

<script type="text/javascript" src="https://cdn.example.com/js_file.js"></script>

Bu durumda site HTTPS'dir, ancak site yalnızca HTTP de olabilir. (JS dosyası başka bir etki alanında.) Kolaylık uğruna aşağıdakileri yapmak için geçerli olup olmadığını merak ediyorum:

<script type="text/javascript" src="//cdn.example.com/js_file.js"></script>

Ben kaldırmak için geçerli olmadığını merak ediyorum http:ya https:?

Test ettiğim her yerde çalışıyor gibi görünüyor, ancak çalışmadığı durumlar var mı?


2
"Her yerde çalışıyor gibi görünüyor" görüntüleri, iframe'ler, link-rels vb. İçin genelleştirilebilir mi? Bu ilginç şeyler, eğer öyleyse.
12345

Evet, bir URI gerektiren herhangi bir yerde çalışmalıdır: resimler, bağlantılar, vb. Bunu kullanımda görmek nadir olabilir, ancak mükemmel bir şekilde geçerlidir.
Jeff

1
Tüm bu anlık oylama adamlarıyla ne var? Soru kötü ya da başka bir şey değil, sadece merak ediyorum. Ama eminim Chris'in ilk itibarı bir etkiye sahiptir.
Frederik Wordenskjold

13
@Frederik: Çünkü görünüşe göre çoğu insanın farkında olmadığı büyüleyici ve kullanışlı bir numara.
SLaks

8
@Frederik: Ne?
SLaks

Yanıtlar:


387

Şema içermeyen göreceli bir URL (http: veya https :) RFC 3986 için geçerlidir : "Tekdüzen Kaynak Tanımlayıcısı (URI): Genel Sözdizimi", Bölüm 4.2 . Bir istemci bunu boğarsa, RFC'de belirtilen URI sözdizimine uymadıkları için istemcinin hatasıdır.

Örneğiniz geçerlidir ve çalışmalıdır. Bu göreli URL yöntemini yoğun şekilde trafik işlemleri yapılan sitelerde kullandım ve sıfır şikayetim oldu. Ayrıca, sitelerimizi Firefox, Safari, IE6, IE7 ve Opera'da test ediyoruz. Bu tarayıcıların tümü bu URL biçimini anlar.


30
"İstemci bunu boğarsa, RFC'de belirtilen URI sözdizimine uymadıkları için istemcinin hatasıdır." - Bu ilginç bir soru olduğunu düşünüyorum - ama bir müşterinin "spec" takip edip edemeyeceği bir web uygulamasında yapmak akıllıca olup olmadığını için iyi bir standart değildir.
Matt Howell

6
Bu teknik çok az bilinmesine rağmen, tüm web tarayıcılarında desteklenmektedir. Sadece harika çalışıyor.
Ned Batchelder

8
Google'ın bunu analiz için neden kullanmadığını merak ediyorum. Onlar document.location.protocol yöntemini kullanırlar.
Darryl Hein

5
@Darryl Hein Ben google sadece düzeni değil, aynı zamanda url değiştirir çünkü document.location.protocol yöntemini kullandığına inanıyorum. Belge https şemasını kullanıyorsa SSL.google-analytics.com adresine giderler .
Nick Meldrum

18
Windows XP ağ yığını SNI'yı desteklemediğinden google bunu kullanmaz. Buraya bakın: blogs.msdn.com/b/ieinternals/archive/2009/12/07/… . Bu nedenle IE6 üzerinde Google Analytics komut dosyasının https aracılığıyla yüklenmesine izin vermek bir sertifika hatasına neden olur.
Eilistraee

152

Herhangi bir genel tarayıcıda çalışacağı garanti edilir (% 0.05'ten daha az pazar payına sahip tarayıcıları dikkate almıyorum). Heck, Internet Explorer 3.0'da çalışır.

RFC 3986 , bir URI'yi aşağıdaki bölümlerden oluşan şekilde tanımlar:

     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment

Göreli URI'leri tanımlarken ( Bölüm 5.2 ), her zaman soldan başlayarak bu bölümlerden herhangi birini atlayabilirsiniz. Sahte kodda şöyle görünür:

 result = ""

  if defined(scheme) then
     append scheme to result;
     append ":" to result;
  endif;

  if defined(authority) then
     append "//" to result;
     append authority to result;
  endif;

  append path to result;

  if defined(query) then
     append "?" to result;
     append query to result;
  endif;

  if defined(fragment) then
     append "#" to result;
     append fragment to result;
  endif;

  return result;

Tanımladığınız URI, şemasız göreli bir URI'dır.


1
Evet, sanırım düzen ve otorite her zaman karşılıklı bağımlıydı. Değil, ama yakın zamana kadar karşılaştığım bir şey değil.
Chris

1
Herhangi bir tarayıcıda çalışacağı garanti edilmez. Yalnızca RFC'yi izleyen tarayıcılarda çalışacağı garanti edilir.

2
@Roger Pate: URI için RFC'yi takip etmeyen bir tarayıcı görmedim. Bu standart çok uzun zamandır var ... Sadece IE3.0'da test ettim ve gayet iyi anlıyor. Bu bağlantıları anlamayan bir tarayıcıya düşerseniz, önemli olmayacak kadar marjinal bir tarayıcı olması ihtimali vardır.
Andrew Moore

1
@Andrew: Belki benden farklısın, ama programlama bağlamında "garanti" dediğimde, gerçekten "bunun muhtemelen başarısız olabileceğinin hiçbir yolu yoktur" demek istemiyorum, sadece benim yaptığım popüler uygulamalarda çalışıyor " test ettik. " Bundan büyük bir şey çıkarmak istememiştim, ama bahsetmek için yeterince önemli görünüyordu.

4
@Roger: Evet, ancak web geliştirme bağlamında, marjinal tarayıcılar (<% 0.01 pazar payı) dikkate alınmaz. Bu, Windows'un tüm sürümlerinde bir API'nin mevcut olduğunu söylemek gibidir ve daha sonra birisi Şarap'ta desteklenmeyebileceğini söylemek için gelir ...
Andrew Moore

79

işe yaramadığı durumlar var mı?

Üst sayfa yüklendiyse file://, muhtemelen işe yaramaz ( file://cdn.example.com/js_file.jselbette yerel olarak da sağlayabileceğinizi almaya çalışacaktır ).


19
Yerel makinede html testi çocuklar için bilmeli!
Philip007

argh ... script src="//..."çalışmama şaşmamalı ! Yerel olarak html dosyasını açıyordum!
wisbucky

Bu konuda bir yol bilen var mı?
km6zla

@ ogc-nick: Yerel bir web sunucusu çalıştırabilirsiniz. Sıfır yapılandırma ile bugünlerde bol seçenek. Yine de, başka birçok şey (XHR veya web çalışanları gibi dosya için de çalışmaz: domain)
Thilo

@Thilo Benim için geçici olarak çalışıyor ama Github'ın Elektronu ile bir uygulama yapıyorum ve bu biraz daha karmaşık hale geliyor.
km6zla


25

Burada cevabı HTML'nin Gizli özelliklerinde çoğaltırım :

Protokolden bağımsız bir mutlak yol kullanma:

<img src="//domain.com/img/logo.png"/>

Tarayıcı SSL'de bir sayfayı HTTPS aracılığıyla görüntülüyorsa, o öğeyi https protokolüyle ister, aksi takdirde HTTP ile ister.

Bu, tüm varlık isteklerinizi aynı protokol içinde tutarak IE'deki bu "Güvenli ve Güvenli Olmayan Öğeler İçerir" hata iletisini önler.

Uyarı: Bir <link>stil sayfası için a veya @import'ta kullanıldığında , IE7 ve IE8 dosyayı iki kez indirir . Bununla birlikte, diğer tüm kullanımlar gayet iyi.


17

Protokolü bırakmak kesinlikle geçerlidir. URL spesifikasyonu bu konuda yıllardır çok açıktı ve henüz anlamayan bir tarayıcı bulamadım. Bu tekniğin neden daha iyi bilinmediğini bilmiyorum; HTTP / HTTPS sınırlarını aşmanın zorlu sorununa mükemmel bir çözümdür. Burada daha fazlası: Http-https geçişleri ve göreli URL'ler


7

işe yaramadığı durumlar var mı?

Bunu sadece karışıma atmak için, yerel bir sunucu üzerinde geliştiriyorsanız, çalışmayabilir. Aksi tarayıcı farz edebilir, bir plan belirtmek gerekir src="//cdn.example.com/js_file.js"ise src="file://cdn.example.com/js_file.js"yerel olarak bu kaynağı barındıran değiliz çünkü kıracak olan.

Microsoft Internet Explorer buna özellikle duyarlı gibi görünüyor, şu soruya bakın: localhost (WAMP) üzerinde Internet Explorer'da jQuery yüklenemiyor

Muhtemelen her zaman tüm ortamlarınızda en az değişiklik gerektiren bir çözüm bulmaya çalışacaksınız.

HTML5Boilerplate tarafından kullanılan çözüm , kaynak doğru yüklenmediğinde bir geri dönüşe sahip olmaktır , ancak bu yalnızca bir onay eklerseniz çalışır:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- If jQuery is not defined, something went wrong and we'll load the local file -->
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>

GÜNCELLEME: HTML5Boilerplate artık <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.jsprotokole bağlı URL'leri kullanımdan kaldırmaya karar verdikten sonra kullanıyor , bkz. [Burada] [3].


4

Gnud'un referansını takiben, RFC 3986 bölüm 5.2 :

Şema bileşeni, başvurunun bir şema adıyla başladığını belirten tanımlanırsa, başvuru mutlak bir URI olarak yorumlanır ve işimiz tamamlanır. Aksi takdirde, referans URI'nin şeması temel URI'nin şema bileşeninden devralınır .

Yani //doğrudur :-)


3

Evet, bu RFC 3986 , bölüm 5.2'de belgelenmiştir :

(değiştir: Hata! RFC referansım eski oldu).


3

Diğer cevapların belirttiği gibi, bu gerçekten doğrudur. Yine de, bazı web tarayıcılarının bunlar için sunucunuzda yerel bir URL gibi isteyerek 404'ler ayarlayacağını unutmayın. (Çift eğik çizgiyi dikkate almazlar ve tek bir eğik çizgi gibi davranırlar).

Bunları yakalamak ve yönlendirmek için web sunucunuzda bir kural ayarlamak isteyebilirsiniz.

Örneğin, Nginx ile şöyle bir şey eklersiniz:

location ~* /(?<redirect_domain>((([a-z]|[0-9]|\-)+)\.)+([a-z])+)/(?<redirect_path>.*) {
  return 301 $scheme:/$redirect_domain/$redirect_path;
}

Bununla birlikte, URI'lerinizde nokta kullanırsanız, özgüllüğü artırmanız gerektiğini veya bunun bu sayfaları mevcut olmayan alanlara yönlendireceğini unutmayın.

Ayrıca, bu, her sorgu için çalıştırılması oldukça büyük bir regex - bence, uyumlu tarayıcıların çoğunda (hafif) bir performansta 404'lü uyumlu olmayan tarayıcıları cezalandırmaya değer.


3

//Somedomain.com'u JS dosyalarına referans olarak kullanırken günlüklerimizde 404 hataları görüyoruz.

404'lere neden olan referanslar şöyle görünür: ref:

<script src="//somedomain.com/somescript.js" />

404 istek:

http://mydomain.com//somedomain.com/somescript.js

Bu web sunucu günlüklerinde düzenli gösterilmesini ile, söylemek güvenli olduğunu: Tüm tarayıcılar ve Botlar DO DEĞİL namus RFC 3986 bölüm 4.2. En güvenli bahis, mümkün olduğunda protokolü dahil etmektir.


Evet, ondan biraz uzaklaştım, ama 404'lerden dolayı değil (404'leri hiç görmedim ... bir bot onurlandırmazsa, daha az umursamıştım) - çünkü artık kaynak yüklemiyorum diğer CDN'ler bu yüzden bunu yapmak zorunda değilim (bunun yerine mümkün olduğunca 1 veya 2 dosyaya küçültmek).
Darryl Hein

1
Lütfen protokolü ekleyin. Cordova uygulamamda protokosuz refs sonu.
pgorsira

3

1. Özet

2019 için cevap: yine de protokole bağlı URL'ler kullanabilirsiniz, ancak bu teknik bir anti-desen .

Ayrıca:

  1. Geliştirme konusunda sorunlarınız olabilir.
  2. Bazı üçüncü taraf araçlar bunları desteklemeyebilir.

Protokole bağlı URL'lerden https://ona geçiş yapmak iyi olurdu.


2. Alaka Düzeyi

Bu cevap Ocak 2019 için geçerlidir. Gelecekte, bu cevabın verileri eski olabilir.


3. Anti-desen

3.1. yargılama

Paul Irish - ön uç mühendis ve Google Chrome için bir geliştirici savunucusu - Aralık 2014'te yaz :

Artık SSL herkes için teşvik edildiğinden ve performans kaygıları olmadığından , bu teknik artık bir anti-kalıptır . İhtiyacınız olan varlık SSL'de varsa, her zaman https://varlığı kullanın .

Snippet'in HTTP üzerinden istekte bulunmasına izin vermek, en son GitHub Man-on-the-side saldırısı gibi saldırıların kapısını açar . Siteniz HTTP'de olsa bile HTTPS öğeleri istemek her zaman güvenlidir, ancak bunun tersi doğru değildir .

3.2. Başka bağlantılar

3.3. Örnekler


4. Geliştirme süreci

Örneğin, temiz konsol kullanmaya çalışıyorum .

  • Örnek dosya KiraCleanConsole__cdn_links_demo.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>clean-console without protocol demonstration</title>
    <!-- Really dead link -->
    <script src="https://unpkg.com/bowser@latest/bowser.min.js"></script>
    <!-- Package exists; link without “https:” -->
    <script src="//cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
    <!-- Package exists: link with “https:” -->
    <script src="https://cdn.jsdelivr.net/npm/gemini-scrollbar/index.js"></script>
</head>
<body>
    Kira Goddess!
</body>
</html>
  • çıktı:
D:\SashaDebugging>clean-console -i KiraCleanConsole__cdn_links_demo.html
checking KiraCleanConsole__cdn_links_demo.html
phantomjs: opening page KiraCleanConsole__cdn_links_demo.html

phantomjs: Unable to load resource (#3URL:file://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js)


phantomjs:   phantomjs://code/runner.js:30 in onResourceError
Error code: 203. Description: Error opening //cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js: The network path was not found.

  phantomjs://code/runner.js:31 in onResourceError

phantomjs: Unable to load resource (#5URL:https://unpkg.com/bowser@2.1.0/bowser.min.js)


phantomjs:   phantomjs://code/runner.js:30 in onResourceError
Error code: 203. Description: Error downloading https://unpkg.com/bowser@2.1.0/bowser.min.js - server replied: Not Found

  phantomjs://code/runner.js:31 in onResourceError

phantomjs: Checking errors after sleeping for 1000ms
2 error(s) on KiraCleanConsole__cdn_links_demo.html

phantomjs process exited with code 2

Bağlantı //cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.jsgeçerli, ancak bir hata alıyorum.

Dikkat edin file://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.jsve Thilo ve bg17aw cevaplarını okuyun file://.

Bu davranışı bilmiyordum ve çağrı cihazları için neden böyle problemlerim olduğunu anlayamadım .


5. Üçüncü taraf araçları

Kullandığım tıklanabilir URL'ler Sublime Text paketi. Kullanın, sadece metin düzenleyicimdeki bağlantıları tarayıcıda açabilirim.

CSS bağlantıları örnekleri

Örnekteki her iki bağlantı da geçerlidir. Ancak ilk bağlantıyı tarayıcıda başarıyla açabildiğim Tıklanabilir URL'ler, ikinci bağlantı - hayır. Bu çok uygun olmayabilir.


6. Sonuç

Evet:

  1. Öğedeki gibi sorunlarınız varsa Developing process, geliştirme iş akışınızı ayarlayabilirsiniz.
  2. Maddede olduğu gibi sorunlarınız Third-party toolsolursa, araçlara katkıda bulunabilirsiniz.

Ancak bu ek sorunlara ihtiyacınız yok. Anti-patternÖğedeki: protokole bağlı URL'lerdeki bağlantılara göre bilgileri okuyun .


2

Html5-boilerplate üzerinde gördüğüm desen :

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.10.2.min.js"><\/script>')</script>

Bu gibi farklı programları üzerine sorunsuz http, https, file.


Bu artık doğru değil, bkz. Stackoverflow.com/a/37609402/2237601 veya burada , şimdi https://her şey için kullanıyorlar
bg17aw

@ bg17aw Her https://yerde kullanmayla ilgili sorun, tüm harici bağlantılarınızı gerçekten destekleyip desteklemediklerini kontrol etmek ve bunları değiştirmek içinhttp:// (aksi takdirde çalışmaz). Bu, çok sayıda bağlantıyla zahmetli olabilir.
tomasz86

@ tomasz86 noktayı kaçırıyorsunuz, sadece CDN'lerden gelen içeriğe bağlanma örneğine başvurdum. https: // günümüzde bunun için zorunludur. Cevap ayrıca belirli bir durumdan (html5-boilerplate) bahsediyor. CDN'ler her zaman https kullandığından, "http için kontrol etme" diye bir şey yoktur.
bg17aw

@ bg17aw Bu doğrudur, ancak buradaki genel soru sadece CDN'ler ile ilgili değildir. Sadece bu cevap / yorumu okuyarak https://, doğru olmayan tüm bağlantılarda kullanılması gerektiğini (veya kullanılabileceğini) düşünmek kolaydır .
tomasz86

@ tomasz86 Birden fazla cevaba sahip olmanın güzelliği, hiçbiri mükemmel olmasa da (eğer bir cevap mükemmel olursa, diğerlerinin silinmesi gerekir), bir kaçını okumak bize daha geniş bir bakış açısı kazandırır. Bu durumda, cevap "html5boilerplate üzerindeki desen ..." diyor ve benim yorumum bu cevabı "artık html5-boilerplate'deki desen değil" ifadesini kullanarak güncellemektedir. Bu kadar. Bu özel cevaba gerekli bir ekleme. Ayrıca lütfen asıl sorunun gerçekten CDN'lerle ilgili olduğunu unutmayın!
bg17aw

1

Örneğiniz harici bir etki alanına bağlandığından, HTTPS kullanıyorsanız harici etki alanının SSL için de ayarlandığını doğrulamanız gerekir. Aksi takdirde, kullanıcılarınız SSL hataları ve / veya 404 hataları görebilir (örn. Plesk'in eski sürümleri HTTP ve HTTPS'yi ayrı klasörlerde depolar). CDN'ler için bu bir sorun olmamalı, ancak başka herhangi bir web sitesi için olabilir.

Bir yan notta, eski bir web sitesini güncellediğinde test edildi ve ayrıca bir META REFRESH'in url = bölümünde çalışıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.