Có hợp lệ để thay thế http: // bằng // trong một tập lệnh <script src = Cảnh http: // phiên bản> không?


458

Tôi có yếu tố sau:

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

Trong trường hợp này, trang web là HTTPS, nhưng trang web cũng có thể chỉ là HTTP. (Tệp JS nằm trên một tên miền khác.) Tôi tự hỏi liệu nó có hợp lệ để thực hiện các thao tác sau vì mục đích thuận tiện không:

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

Tôi đang tự hỏi nếu nó hợp lệ để loại bỏ http:hoặc https:?

Nó dường như hoạt động ở mọi nơi tôi đã thử nghiệm, nhưng có trường hợp nào nó không hoạt động không?


2
"Nó dường như hoạt động ở mọi nơi" có thể được khái quát thành hình ảnh, iframe, link-rels, v.v.? Đây là công cụ thú vị, nếu vậy.
12345

Phải, nó sẽ hoạt động ở bất kỳ nơi nào cần URI: hình ảnh, liên kết, v.v. Có thể hiếm khi thấy điều này được sử dụng, nhưng nó hoàn toàn hợp lệ.
Jeff

1
Những gì với tất cả những người nâng cao ngay lập tức? Không phải là câu hỏi là xấu hay bất cứ điều gì, tôi chỉ tò mò. Nhưng tôi cá rằng danh tiếng nội bộ của Chris có ảnh hưởng.
Frederik Wordenskjold

13
@Frederik: Bởi vì đó là một mẹo hấp dẫn và hữu ích mà hầu hết mọi người dường như không biết.
SLaks

8
@Frederik: Cái gì?
SLaks

Câu trả lời:


387

Một URL tương đối không có lược đồ (http: hoặc https :) là hợp lệ, theo RFC 3986: "Mã định danh tài nguyên đồng nhất (URI): Cú pháp chung", Mục 4.2 . Nếu một khách hàng bóp nghẹt nó, thì đó là lỗi của khách hàng vì họ không tuân thủ cú pháp URI được chỉ định trong RFC.

Ví dụ của bạn là hợp lệ và nên hoạt động. Bản thân tôi đã sử dụng phương pháp URL tương đối đó trên các trang web bị buôn bán nặng và không có khiếu nại. Ngoài ra, chúng tôi kiểm tra các trang web của chúng tôi trong Firefox, Safari, IE6, IE7 và Opera. Các trình duyệt này đều hiểu định dạng URL đó.


30
"Nếu một khách hàng bóp nghẹt nó, thì đó là lỗi của khách hàng vì họ không tuân thủ cú pháp URI được chỉ định trong RFC." - Tôi nghĩ rằng đây là một câu hỏi thú vị - nhưng liệu khách hàng có tuân theo "thông số kỹ thuật" hầu như không phải là một tiêu chuẩn tốt cho việc liệu có nên làm trong một ứng dụng web hay không.
Matt Howell

6
Mặc dù kỹ thuật này dường như ít được biết đến, nhưng nó được hỗ trợ trong tất cả các trình duyệt web. Nó hoạt động chỉ là tuyệt vời.
Ned Batchelder

8
Tôi tự hỏi tại sao google không sử dụng điều này để phân tích. Họ sử dụng phương thức document.location.protatio.
Darryl Hein

5
@Darryl Hein Tôi tin rằng google sử dụng phương thức document.location.protatio vì nó cũng sửa đổi url, không chỉ lược đồ. Họ truy cập SSL.google-analytics.com nếu tài liệu đang sử dụng lược đồ https.
Nick Meldrum

18
google không sử dụng điều này vì ngăn xếp mạng Windows XP không hỗ trợ SNI. Xem tại đây: blog.msdn.com/b/ieiternals/archive/2009/12/07/ . Do đó, việc cho phép tập lệnh phân tích google được tải qua https trên IE6 sẽ dẫn đến lỗi chứng chỉ.
Eilistraee

152

Nó được đảm bảo để hoạt động trong bất kỳ trình duyệt chính nào (Tôi không xem xét các trình duyệt có thị phần dưới 0,05%). Heck, nó hoạt động trong Internet Explorer 3.0.

RFC 3986 định nghĩa một URI bao gồm các phần sau:

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

Khi xác định các URI tương đối ( Mục 5.2 ), bạn có thể bỏ qua bất kỳ phần nào trong số đó, luôn bắt đầu từ bên trái. Trong mã giả, nó trông như thế này:

 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;

URI mà bạn đang mô tả là một URI tương đối không có lược đồ.


1
Vâng tôi đoán tôi nghĩ rằng kế hoạch và thẩm quyền luôn luôn phụ thuộc lẫn nhau. Điều đó có nghĩa là nó không phải, nhưng nó không phải là thứ tôi đã gặp cho đến gần đây.
Chris

1
Nó không được đảm bảo để làm việc trong bất kỳ trình duyệt. Nó được đảm bảo chỉ hoạt động trong các trình duyệt tuân theo RFC.

2
@Roger Pate: Tôi vẫn chưa thấy trình duyệt không tuân theo RFC cho URI. Tiêu chuẩn cụ thể đó đã có từ rất lâu ... Tôi mới thử nghiệm nó trong IE3.0 và nó hiểu nó hoàn toàn ổn. Nếu bạn rơi vào một trình duyệt không hiểu các liên kết đó, rất có thể đó là một trình duyệt ngoài lề đến nỗi nó không thành vấn đề.
Andrew Moore

1
@Andrew: Có thể bạn khác với tôi, nhưng khi tôi nói "đảm bảo" trong ngữ cảnh lập trình, tôi thực sự có nghĩa là "không có cách nào có thể, bao giờ thất bại", không chỉ "nó chỉ hoạt động trong các triển khai phổ biến mà tôi ' đã thử nghiệm. " Tôi không có ý định làm cho nó lớn, nhưng nó dường như đủ quan trọng để đề cập.

4
@Roger: Có, nhưng trong bối cảnh phát triển web, các trình duyệt cận biên (<0,01% thị phần) không được xem xét. Giống như nói rằng một API có mặt trong tất cả các phiên bản Windows và sau đó ai đó đến để nói rằng nó có thể không được hỗ trợ trong Wine ...
Andrew Moore

79

Có trường hợp nào nó không hoạt động?

Nếu trang mẹ được tải từ file://đó, thì có lẽ nó không hoạt động (nó sẽ cố gắng lấy file://cdn.example.com/js_file.js, tất nhiên bạn cũng có thể cung cấp tại địa phương).


19
Phải biết cho những người thử nghiệm html trên máy cục bộ!
Philip007

argh ... không có gì lạ khi tôi script src="//..."không làm việc Tôi đã mở tệp html cục bộ!
wvducky

Bất cứ ai biết một cách xung quanh này?
km6zla

@ ogc-nick: Bạn có thể chạy một máy chủ web cục bộ. Nhiều lựa chọn ngày nay, với cấu hình bằng không. Dù sao thì bạn cũng muốn điều đó, vì nhiều thứ khác (chẳng hạn như XHR hoặc nhân viên web cũng không hoạt động cho tệp: domain)
Thilo

@Thilo Điều đó đã làm việc tạm thời với tôi nhưng tôi đang tạo một ứng dụng với Electron của Github và điều đó phức tạp hơn một chút.
km6zla 6/07/2015


25

Ở đây tôi nhân đôi câu trả lời trong các tính năng ẩn của HTML :

Sử dụng đường dẫn tuyệt đối độc lập giao thức:

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

Nếu trình duyệt đang xem một trang bằng SSL thông qua HTTPS, thì nó sẽ yêu cầu tài sản đó với giao thức https, nếu không, nó sẽ yêu cầu nó bằng HTTP.

Điều này ngăn chặn thông báo lỗi "Trang này chứa cả mục an toàn và không bảo mật" trong IE, giữ tất cả các yêu cầu tài sản của bạn trong cùng một giao thức.

Hãy cẩn thận: Khi được sử dụng trên <link>hoặc @import cho biểu định kiểu, IE7 và IE8 tải xuống tệp hai lần . Tất cả các sử dụng khác, tuy nhiên, chỉ là tốt.


17

Nó là hoàn toàn hợp lệ để rời khỏi giao thức. Thông số URL đã rất rõ ràng về điều này trong nhiều năm và tôi vẫn chưa tìm thấy một trình duyệt không hiểu nó. Tôi không biết tại sao kỹ thuật này không được biết đến nhiều hơn; đó là giải pháp hoàn hảo cho vấn đề nhức nhối khi vượt qua ranh giới HTTP / HTTPS. Xem thêm tại đây: Chuyển tiếp http-https và URL tương đối


7

Có trường hợp nào nó không hoạt động?

Chỉ cần ném cái này vào hỗn hợp, nếu bạn đang phát triển trên một máy chủ cục bộ, nó có thể không hoạt động. Bạn cần phải xác định một chương trình, nếu không thì trình duyệt có thể cho rằng src="//cdn.example.com/js_file.js"src="file://cdn.example.com/js_file.js", sẽ phá vỡ kể từ khi bạn không lưu trữ tài nguyên này tại địa phương.

Microsoft Internet Explorer dường như đặc biệt nhạy cảm với điều này, hãy xem câu hỏi này: Không thể tải jQuery trong Internet Explorer trên localhost (WAMP)

Bạn có thể sẽ luôn cố gắng tìm một giải pháp hoạt động trên tất cả các môi trường của bạn với số lượng sửa đổi ít nhất cần thiết.

Giải pháp được sử dụng bởi HTML5Boilerplate là dự phòng khi tài nguyên không được tải chính xác, nhưng nó chỉ hoạt động nếu bạn kết hợp kiểm tra:

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

CẬP NHẬT: HTML5Boilerplate hiện sử dụng <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.jssau khi quyết định loại bỏ các URL tương đối của giao thức, xem [tại đây] [3].


4

Theo tham chiếu của gnud, RFC 3986 phần 5.2 nói:

Nếu thành phần lược đồ được xác định, chỉ ra rằng tham chiếu bắt đầu bằng tên lược đồ, thì tham chiếu được hiểu là URI tuyệt đối và chúng ta đã hoàn thành. Mặt khác, lược đồ của URI tham chiếu được kế thừa từ thành phần lược đồ của URI cơ sở .

Vậy //là đúng :-)


3

Có, điều này được ghi lại trong RFC 3986 , phần 5.2:

(chỉnh sửa: Rất tiếc, tham chiếu RFC của tôi đã lỗi thời).


3

Nó thực sự chính xác, như các câu trả lời khác đã nêu. Mặc dù vậy, bạn cần lưu ý rằng một số trình thu thập dữ liệu web sẽ đặt ra 404 cho những điều này bằng cách yêu cầu chúng trên máy chủ của bạn như thể một URL cục bộ. (Họ bỏ qua dấu gạch chéo kép và coi nó là một dấu gạch chéo).

Bạn có thể muốn thiết lập một quy tắc trên máy chủ web của mình để nắm bắt những điều này và chuyển hướng chúng.

Ví dụ: với Nginx, bạn sẽ thêm một cái gì đó như:

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

Mặc dù vậy, xin lưu ý rằng nếu bạn sử dụng dấu chấm trong URI của mình, bạn sẽ cần tăng tính đặc hiệu hoặc cuối cùng nó sẽ chuyển hướng các trang đó sang các miền không tồn tại.

Ngoài ra, đây là một regex khá lớn đang chạy cho mỗi truy vấn - theo tôi, đáng để trừng phạt các trình duyệt không tuân thủ với 404s trên hiệu suất (nhẹ) đánh vào phần lớn các trình duyệt tuân thủ.


3

Chúng tôi đang thấy lỗi 404 trong nhật ký của mình khi sử dụng //somedomain.com làm tài liệu tham khảo cho các tệp JS.

Các tham chiếu khiến 404 xuất hiện như thế này: ref:

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

Yêu cầu 404:

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

Với những thứ này xuất hiện thường xuyên trong nhật ký máy chủ web của chúng tôi, có thể nói rằng: Tất cả các trình duyệt và Bots KHÔNG tôn trọng RFC 3986 phần 4.2. Đặt cược an toàn nhất là bao gồm các giao thức bất cứ khi nào có thể.


Vâng, tôi đã loại bỏ nó, nhưng không phải vì 404 (Tôi chưa bao giờ thấy bất kỳ 404 nào ... nếu một bot không tôn trọng nó, tôi có thể quan tâm ít hơn) - vì tôi không còn tải tài nguyên từ các CDN khác vì vậy tôi không cần phải làm điều này (thay vào đó tôi thu nhỏ càng nhiều càng tốt vào 1 hoặc 2 tệp).
Darryl Hein

1
Vui lòng bao gồm các giao thức. Giao thức giới thiệu ít giao thức bị hỏng trong ứng dụng Cordova của tôi.
pgorsira 14/2/2015

3

1. Tóm tắt

Trả lời cho năm 2019: bạn vẫn có thể sử dụng các URL liên quan đến giao thức, nhưng kỹ thuật này là một mô hình chống .

Cũng thế:

  1. Bạn có thể có vấn đề trong việc phát triển.
  2. Một số công cụ của bên thứ ba có thể không hỗ trợ chúng.

Di chuyển từ các URL liên quan đến giao thức đến https://nó sẽ rất tuyệt.


2. Sự liên quan

Câu trả lời này có liên quan đến tháng 1 năm 2019. Trong tương lai, dữ liệu của câu trả lời này có thể bị lỗi thời.


3. Chống hoa văn

3.1. Luận cứ

Paul Irish - kỹ sư đầu cuối và là người ủng hộ nhà phát triển cho Google Chrome - viết vào năm 2014, tháng 12 :

Bây giờ SSL được khuyến khích cho tất cả mọi ngườikhông có mối quan tâm về hiệu suất , kỹ thuật này hiện là một mô hình chống . Nếu tài sản bạn cần có sẵn trên SSL, thì hãy luôn sử dụng https://tài sản đó.

Việc cho phép đoạn mã yêu cầu qua HTTP sẽ mở ra cơ hội cho các cuộc tấn công như cuộc tấn công Man-on-the-side gần đây của GitHub . Luôn luôn an toàn khi yêu cầu tài sản HTTPS ngay cả khi trang web của bạn sử dụng HTTP, tuy nhiên điều ngược lại là không đúng .

3.2. Một liên kết khác

3.3. Ví dụ


4. Quá trình phát triển

Ví dụ, tôi cố gắng sử dụng giao diện điều khiển sạch .

  • Tệp ví dụ 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>
  • đầu ra:
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

Liên kết //cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.jslà hợp lệ, nhưng tôi nhận được một lỗi.

Hãy chú ý file://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.jsvà đọc câu trả lời của Thilobg17aw về file://.

Tôi không biết về hành vi này và không thể hiểu tại sao tôi gặp vấn đề như thế này đối với máy nhắn tin .


5. Công cụ của bên thứ ba

Tôi sử dụng gói URL có thể nhấp vào URL có thể nhấp . Sử dụng nó, tôi chỉ có thể mở các liên kết từ trình soạn thảo văn bản của tôi trong trình duyệt.

Ví dụ liên kết CSS

Cả hai liên kết trong ví dụ là hợp lệ. Nhưng liên kết đầu tiên tôi có thể mở thành công trong trình duyệt sử dụng URL có thể nhấp, liên kết thứ hai - không. Điều này có thể không được thuận tiện.


6. Kết luận

Đúng:

  1. Nếu bạn gặp vấn đề như trong Developing processmục, bạn có thể đặt quy trình phát triển của mình.
  2. Khác bạn có vấn đề như trong Third-party toolsmục, bạn có thể đóng góp công cụ.

Nhưng bạn không cần thêm vấn đề này. Đọc thông tin theo các liên kết trong Anti-patternmục: URL liên quan đến giao thức đã lỗi thời.


2

Mẫu tôi thấy trên html5-soạn sẵn là:

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

Nó chạy rất tốt trên các chương trình khác nhau như http, https, file.


Điều này không còn đúng nữa, xem stackoverflow.com/a/37609402/2237601 hoặc tại đây , giờ đây họ sử dụng https://cho mọi thứ
bg17aw

@ bg17aw Vấn đề với việc sử dụng https://ở mọi nơi là sau đó bạn phải tiếp tục kiểm tra tất cả các liên kết bên ngoài của mình để xem chúng có thực sự hỗ trợ hay không và thay đổi chúng thành http://nếu chúng không hoạt động (vì nếu không chúng sẽ không hoạt động). Điều này có thể gây rắc rối với một số lượng lớn các liên kết.
tomasz86

@ tomasz86 bạn đang thiếu điểm, tôi chỉ tham gia vào trường hợp cụ thể liên kết đến nội dung từ CDN. https: // là bắt buộc cho ngày hôm nay. Câu trả lời cũng nói về một trường hợp cụ thể (html5-cái nồi). Không có "kiểm tra http" như bạn nói, vì CDN luôn sử dụng https ngay bây giờ.
bg17aw

@ bg17aw Điều đó đúng nhưng câu hỏi chung ở đây không chỉ là về CDN. Bằng cách chỉ đọc câu trả lời / nhận xét này, thật dễ dàng để nghĩ rằng https://nên (hoặc có thể) được sử dụng trong tất cả các liên kết không chính xác.
tomasz86

@ tomasz86 Vẻ đẹp của việc có nhiều câu trả lời là trong khi không có câu trả lời nào là hoàn hảo (nếu một câu trả lời là hoàn hảo, thì những câu hỏi khác sẽ cần phải bị xóa), đọc một vài trong số chúng cho chúng ta cái nhìn rộng hơn. Trong trường hợp này, câu trả lời cho biết "mẫu trên html5boilerplate là ..." và nhận xét của tôi cập nhật câu trả lời này có đề cập đến "đó không còn là mẫu trên html5-nồi hơi". Đó là nó. Một bổ sung cần thiết cho câu trả lời cụ thể này. Ngoài ra xin lưu ý câu hỏi ban đầu thực sự là về CDN!
bg17aw

1

Vì ví dụ của bạn đang liên kết với một tên miền bên ngoài, nếu bạn đang sử dụng HTTPS thì bạn nên xác minh rằng tên miền bên ngoài cũng được thiết lập cho SSL. Mặt khác, người dùng của bạn có thể thấy lỗi SSL và / hoặc lỗi 404 (ví dụ: các phiên bản cũ hơn của Plesk lưu trữ HTTP và HTTPS trong các thư mục riêng). Đối với CDN, nó không phải là một vấn đề nhưng đối với bất kỳ trang web nào khác thì nó có thể.

Bên cạnh đó, đã kiểm tra trong khi cập nhật một trang web cũ và cũng hoạt động trong url = một phần của META REFRESH.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.