Tại sao đặc tả HTML \ DOM không cho phép các siêu liên kết đặt tiêu đề chấp nhận?


10

Mục đích của Accepttiêu đề từ máy khách là cho máy chủ biết loại dữ liệu nào sẽ chấp nhận như một phản hồi cho yêu cầu của nó. Chúng tôi có thể đặt tiêu đề này trong các cuộc gọi HTTP không đồng bộ trong Javascript, nhưng không phải trong HTML.

Ví dụ, hãy xem xét một liên kết như <a href="https://softwareengineering.stackexchange.com/some/resource">Get as CSV</a>. Nếu một thuộc tính như accept="text/csv"được cho phép và trình duyệt giải thích rằng để gửi Accept: text/csvtiêu đề với yêu cầu đó, máy chủ có thể đáp ứng ngữ nghĩa của yêu cầu. Nếu không có nó, chúng ta có thể tạo một liên kết như <a href="https://softwareengineering.stackexchange.com/some/resource?format=csv">Get as CSV</a>, và máy chủ phải trả lời tham số chuỗi truy vấn tùy ý thay thế.

Các lý do, cả về kỹ thuật và lịch sử, đằng sau đặc tả HTML \ DOM không cho phép cài đặt Accepttiêu đề thông qua đánh dấu là gì?


2
Web là một nền tảng di sản bị cản trở bởi nỗi sợ thay đổi và ủy ban tiêu chuẩn chậm: wtfhtmlcss.com wtfjs.com
Den

Câu trả lời:


9

Bởi vì các tiêu đề không phải là một phần của URL. URL phải tự xác định tài nguyên và nên thực hiện nó một cách độc đáo. Các tiêu đề Accept(và hữu ích hơn Accept-Encoding) sẽ không ảnh hưởng đến ngữ nghĩa của yêu cầu. Họ nên chỉ ra khả năng của khách hàng để máy chủ có thể định dạng phản hồi phù hợp.

Nếu bạn thực hiện cuộc gọi HTTP từ JavaScript, mã JavaScript của bạn là máy khách và do đó, nó sẽ được đặt tiêu đề. Nhưng đối với liên kết HTML, trình duyệt là ứng dụng khách và do đó nó được chọn.

Nếu bạn muốn cung cấp CSV cho người dùng, tài nguyên được liên kết thường ở định dạng cố định. Hãy tưởng tượng người dùng làm

Copy Link Address

$ wgetPasteEnter

Đó là một điều hợp pháp để họ làm vì nhiều lý do. Và bởi vì liên kết đã hứa với họ CSV, đó là những gì họ sẽ mong đợi. Nhưng wget sẽ không nhận được bất kỳ thuộc tính nào khác của liên kết. Chỉ URL. Vì vậy, thông tin nên được mã hóa trong URL.

Trong thực tế, không có nhiều cách sử dụng cho Accepttiêu đề, bởi vì hầu hết các tài nguyên chỉ có định dạng của chúng và không có nhiều ý nghĩa trong việc khác. Điều Accept-Encodingnày là hữu ích; nếu khách hàng nói Accept-Encoding: gzip,deflateđiều đó có nghĩa là khách hàng có thể giải nén trong suốt . Nhưng về việc sử dụng duy nhất tôi có thể nghĩ đến Acceptlà các định dạng hình ảnh và video, ví dụ như để cung cấp thay thế cho các trình duyệt không hỗ trợ nói image/svg+xmlhoặc video/webm. Ngoại trừ các trình duyệt dường như không thực sự quảng cáo định dạng phương tiện nào họ hỗ trợ, vì vậy nó không hoạt động. Và HTML đã chọn thực hiện cơ chế khác nhau, linh hoạt hơn một chút. Và một vài loại dữ liệu khác có một số định dạng thay thế được triển khai rộng rãi để lựa chọn.


Ngoài ra, với âm thanh và video có các thẻ audiovideo. Vì vậy, vấn đề đó bây giờ (hy vọng) được giảm nhẹ đến mức được khắc phục. Vâng, đối với các trình duyệt tương thích với HTML5.
Bắn Parthian

@ParthianShot: Đúng. Tôi không làm các ứng dụng web, vì vậy tôi không nhớ nó hoạt động như thế nào. Rõ ràng là phù hợp hơn để cung cấp cho khách hàng một danh sách để lựa chọn (thường là ngắn) so với việc có danh sách khách hàng tất cả những điều nó hỗ trợ.
Jan Hudec

URL phải xác định tài nguyên này chính xác là lý do tại sao tôi muốn thêm tham số làm tiêu đề hữu ích để theo dõi nội dung của người dùng, như vị trí của anh ta khi anh ta nhấp hoặc nếu trước đó anh ta đã được chuyển hướng từ đâu đó, thì đó là cách tốt hơn để làm điều này?
santiago arizti

3

Bởi vì Accept:tiêu đề nhằm chỉ ra loại tài liệu nào mà trình duyệt của người dùng có thể xử lý chính xác và đây không phải là thông tin mà bạn, với tư cách là tác giả của trang web, có.

Cụ thể, lý do giao thức HTTP cung cấp tiêu đề Chấp nhận: là để cho phép chọn một loại tệp thích hợp khi cùng một tài liệu có sẵn ở nhiều dạng. Ví dụ, giả sử tôi đang liên kết đến một hình ảnh; trình duyệt của tôi có thể hiển thị hình ảnh JPEG hoặc Tiff, nhưng có thể không có khả năng hiển thị hình ảnh RAW. Trình duyệt sẽ chỉ ra điều này bằng cách gửi các tiêu đề sau với yêu cầu hình ảnh:

Accept: image/jpeg,image/tiff

Bây giờ, nếu máy chủ có thể phân phát một hình ảnh nhất định dưới dạng RAW hoặc TIFF, thì nó sẽ phản hồi với phiên bản TIFF của hình ảnh (và đặt Content-Type:tiêu đề để chỉ ra loại hình đã chọn).

Điều gì có ý nghĩa đối với tác giả của trang web để ghi đè các lựa chọn mà trình duyệt gửi? Nếu tôi thêm một accept="image/raw"thuộc tính giả định , trình duyệt vẫn không thể hiển thị hình ảnh thô - nhưng máy chủ sẽ gửi nó.


Chơi lô tô. Ứng dụng không thể quyết định loại MIME nào trình duyệt chấp nhận.
Svidgen

2

Một URI được dự định để xác định một tài nguyên .

Tài nguyên đề cập đến những điều thực tế đang được lấy. Trên một trang web, đó thường là một trang . Trong API REST, thông thường nó sẽ là một thực thể - người, hồ sơ, widget, ảnh, v.v.

Các tiêu đề HTTP cho máy chủ biết những điều về máy khách - chúng không mô tả bất cứ điều gì về chính tài nguyên đó hoặc cung cấp bất kỳ trợ giúp nào trong việc định vị tài nguyên đó.

Ví dụ:

  • Accept-Encoding báo cho máy chủ biết rằng máy khách biết cách chuyển đổi hoặc giải nén nội dung nhất định.
  • Accept-Language nói với máy chủ rằng máy khách đang ở một miền địa phương nhất định và thích nội dung ở miền địa phương đó.
  • Authorization nói với máy chủ rằng máy khách nghĩ rằng nó được phép truy cập vào một tài nguyên được bảo vệ.

Một chủ đề phổ biến với phần lớn các tiêu đề yêu cầu này là máy chủ không bắt buộc phải tôn vinh chúng. Một Accept-Encodingtrong số gzipđó không đảm bảo rằng phản hồi sẽ được nén. Một Accept-Languagetrong số đó ur-PKcó khả năng bị bỏ qua khi truy cập vào một trang web của Hoa Kỳ, trừ khi họ đặc biệt hỗ trợ tiếng Urdu. Và máy chủ có quyền xác minh Authorizationtiêu đề và trả lại 401 hoặc 403, nếu nó không giống như những gì nó thấy.

Không có tiêu đề nào trong số này được dự định thay đổi mạnh mẽ bất cứ điều gì về tài nguyên mà máy chủ cung cấp để đáp ứng. Các Accepttiêu đề là không khác nhau. Nếu một máy khách chỉ định application/xmlvà máy chủ chỉ hỗ trợ application/json, thì máy chủ sẽ gửi lại JSON - không phải XML. Quan trọng hơn, Accepttiêu đề có thể chỉ định nhiều loại, trong trường hợp đó, máy chủ có thể trả lại bất cứ loại nào nó thích (hoặc không có loại nào). Như bạn có thể tưởng tượng, điều này có thể dễ dàng dẫn đến hành vi không xác định cho người dùng, nhưng hãy bỏ qua điều đó ngay bây giờ.

Mục đích của một siêu liên kếtliên kết đến một trang - trang là một loại tài nguyên nhất định. Hoặc, bạn có thể được chứng minh bằng định nghĩa lỏng lẻo về việc liên kết đơn giản với tài nguyên, ngay cả khi tài nguyên đó là một thứ gì đó không phải là một trang (có thể là hình ảnh hoặc tập dữ liệu). Tuy nhiên, điều chắc chắn không có nghĩa là phải làm là liên kết đến một đại diện cụ thể của tài nguyên. Đó là để khách hàng và máy chủ đàm phán, và máy chủ quyết định cuối cùng.

Accept-Languagelà một ví dụ rõ ràng về lý do tại sao nó có thể có vấn đề khi cho phép các siêu liên kết kiểm soát các tiêu đề. Nó không thực sự có ý nghĩa, nếu bạn nghĩ về nó. Mỗi người dùng kiểm soát sở thích ngôn ngữ của mình; nó được cấu hình trong hệ điều hành và / hoặc trình duyệt. Trình duyệt phải luôn gửi cùng một Accept-Language tiêu đề, bất kể trang nào đang được truy cập. Nếu máy chủ hỗ trợ ngôn ngữ đó, thật tuyệt; nếu không, nó sẽ phản hồi với bất kỳ ngôn ngữ nào mà nó cho là gần nhất.

Nếu điều này có thể được thay đổi bởi các siêu liên kết, thì về cơ bản các liên kết trong nước có thể buộc bạn vào phiên bản tiếng Trung của trang web, ngay cả khi trình duyệt và hệ điều hành của bạn không được định cấu hình để hỗ trợ ngôn ngữ đó. Điều đó không có ý nghĩa. Nếu trang web hỗ trợ tiếng Anh và trình duyệt của bạn là tiếng Anh, thì nó sẽ phản hồi bằng tiếng Anh, bất kể siêu liên kết nói gì.

Tương tự, nếu trình duyệt của bạn biết cách hiển thị XML dưới dạng dữ liệu có cấu trúc và có thể tìm XSL để làm cho nó trông đẹp hơn, nhưng thực sự không biết phải làm gì với JSON ngoài việc loại bỏ nó dưới dạng văn bản thuần túy, sau đó buộc chúng phải Nội dung JSON bằng cách liên kết (nếu điều đó là có thể) là một hành vi thù địch mạnh mẽ của người dùng. Trình duyệt phải luôn là người nói: "Tôi biết cách hiển thị X, nhưng không phải là Y, vì vậy tôi thực sự thích nếu bạn cho tôi X".

Tôi có thể hiểu tại sao bạn có thể nghĩ rằng nó hợp lý khi cho phép người dùng trình duyệt ghi đè quyết định này. Nhưng sự thật của vấn đề là bạn đang nghĩ về một vài trường hợp nhỏ như tải xuống báo cáo; 99% thời gian, khi lựa chọn này tồn tại, người dùng không đủ điều kiện hoặc không có đủ thông tin để thực hiện.

Nói cách khác, hãy tưởng tượng cha mẹ hoặc ông bà của bạn sẽ tải xuống một tệp và được yêu cầu chọn văn bản / csv hoặc văn bản / thuần túy. Họ có khả năng biết sự khác biệt? Tôi không biết về bạn, nhưng tôi thường không thể nhận ra sự khác biệt giữa quảng cáo biểu ngữ và thông báo lỗi, vì vậy không có cách nào họ có thể đưa ra lựa chọn này một cách thông minh. Mặt khác, có thể có một tia hy vọng nếu họ được cung cấp các liên kết riêng để tải xuống "sổ làm việc Excel" hoặc "Chỉ văn bản" - mà chúng thực sự là các tài nguyên riêng biệt , không chỉ là đại diện khác nhau của cùng một tài nguyên và các URI sẽ phản ánh điều đó.

Người dùng không thể dựa vào để hiểu rằng hai thứ này thực sự là cùng một tài nguyên, nhưng đại diện khác nhau. Và không thay đổi mọi thứ về cách thức hoạt động của web ngày hôm nay, chúng ta không thể thừa nhận bất cứ điều gì về những gì họ sẽ làm với siêu liên kết đó. Họ có thể nhấp hoặc họ có thể nhấp chuột phải -> "lưu dưới dạng" hoặc họ có thể sao chép và dán nó vào thanh địa chỉ hoặc họ có thể đang sử dụng trình quản lý tải xuống hoặc họ vẫn có thể đang sử dụng IE6 hoặc họ có thể đang sử dụng một số máy tính bảng hoặc thiết bị di động không có thương hiệu với trình duyệt độc quyền ... và trong nhiều trường hợp này, họ sẽ không có được nội dung họ muốn, bởi vì họ sẽ mất một phần của siêu liên kết tuyên bố loại nội dung hoặc trình duyệt của họ sẽ không hỗ trợ nó.

Thông số HTML có thể được thiết kế 40 năm trước để hỗ trợ thuộc tính loại nội dung trong siêu liên kết không? Có thể, mặc dù như tôi đã mô tả trong một số đoạn đầu tiên, có những lý do mạnh mẽ chống lại nó, đặc biệt là trong thời gian băng thông và tài nguyên máy chủ khan hiếm và ý tưởng có thể tải xuống cùng một báo cáo ở nhiều định dạng (hoặc, thẳng thắn , tải xuống bất kỳ báo cáo nào) thực sự đã không xảy ra với bất cứ ai. Nhưng chắc chắn trong thế giới ngày nay, sẽ thật điên rồ khi thử thêm một cái gì đó như thế vào thông số kỹ thuật; nó sẽ phá vỡ hoàn toàn khả năng tương thích ngược và dẫn đến "hành vi không xác định" đáng sợ trong mọi trình duyệt hiện có.


Nếu một máy khách chỉ định ứng dụng / xml và máy chủ chỉ hỗ trợ ứng dụng / json, thì máy chủ sẽ gửi lại JSON - không phải XML. Vậy thì, lỗi 406 HTTP để làm gì? Để trích dẫn rfc2616: Nếu có trường tiêu đề Chấp nhận và nếu máy chủ không thể gửi phản hồi có thể chấp nhận theo giá trị trường Chấp nhận kết hợp, thì máy chủ NÊN gửi phản hồi 406 (không chấp nhận được).
Jules Randolph

Tuy nhiên, điều chắc chắn không có nghĩa là phải làm là liên kết đến một đại diện cụ thể của tài nguyên. Đó là để khách hàng và máy chủ đàm phán, và máy chủ quyết định cuối cùng. → Và nếu nhà thiết kế ứng dụng muốn tham gia đàm phán thì sao? Có bất kỳ tài liệu tham khảo nào được khẳng định rằng tác nhân người dùng tức là máy khách phải và chỉ là trình duyệt web ? Tôi sẽ rất vui nếu bạn có thể giúp tôi hiểu điều này.
Jules Randolph

0

Câu trả lời chính là một liên kết trong một trang web được dự định sẽ được hiển thị dưới dạng một trang web. Nếu máy chủ web trả về một số loại khác ngoài trang có thể hiển thị (hình ảnh, tệp đã tải xuống, v.v.), thì nội dung có thể được trình duyệt hiển thị hoặc không (có thể được lưu dưới dạng tệp).

Không có cách nào để một liên kết trong một trang web dẫn đến tệp CSS hoặc tệp JavaScript, v.v., được hiển thị đúng trong trình duyệt.

Để đạt được bất cứ điều gì bạn đang cố gắng đạt được (bạn không nói), bạn có thể tạo một liên kết gọi hàm JavaScript cung cấp chức năng bổ sung mà bạn cần.


0

Lý do thực sự khá đơn giản ..

Trình duyệt

Các Acceptstiêu đề được nói đến máy chủ tôi chấp nhận và biết làm thế nào để hiển thị loại nội dung này tập tin / file ....

Javascript

Tại sao bạn có thể thay đổi tiêu đề khi gửi yêu cầu trong javascript, bạn cũng có thể đã tạo ra một cách để acceptloại nội dung mới này nói rằng bạn đã mã hóa thứ gì đó và gửi nó dưới dạng loại tệp encrypted/myencryptionmà javascript của bạn có thể biết cách giải mã nó để nó có thể chấp nhận loại nội dung để nó báo cho máy chủ biết nó có thể chấp nhận nội dung đó không

Liên kết neo <a></a>

Không có gì khác hơn là bảo trình duyệt lấy tệp trong href và kết xuất nó để nếu trình duyệt không thể hiểu nó, hãy thử phân tích nó và hiển thị lời nhắc tải xuống cho tệp. một số máy chủ khắc phục điều này bằng cách chỉ đặt loại thành văn bản / thuần túy và sau đó trình duyệt sẽ chỉ hiển thị văn bản của tệp.

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.