Tôi nên sử dụng mã hóa ký tự nào cho tiêu đề HTTP?


122

Tôi đang sử dụng ký tự đặc biệt HTML "vui nhộn" (✰) (xem http://html5boilerplate.com/ để biết thêm thông tin) cho Servertiêu đề HTTP và tôi đang tự hỏi liệu nó có được "cho phép" theo thông số hay không.

  • Sử dụng Tab Mạng trong các công cụ dành cho nhà phát triển trong Chrome trên Windows Xp Pro SP 3, tôi thấy ✰ ổn.

  • Trong IE8, ✰ không được hiển thị chính xác.

  • Trình xác thực HTML w3.org không hiển thị nó một cách chính xác ( â°thay vào đó sẽ hiển thị " ").

Bây giờ, tôi không quá quan tâm đến các bảng mã ký tự ... và thành thật mà nói, tôi không thực sự quan tâm quá nhiều đến chúng; Tôi chỉ sử dụng UTF-8 một cách mù quáng vì tôi được yêu cầu. :-)


Có phải sự chênh lệch do lỗi trong các trình phân tích cú pháp / trình duyệt / công cụ / (bất kỳ cái gì-chúng-được gọi là) khác nhau gây ra không?

Có thông số kỹ thuật cho điều này hoặc có thể là danh sách các ký tự được phép cho "giá trị" tiêu đề HTTP không?


29
Câu hỏi này sẽ được tốt hơn yêu cầu chung: "Những ký tự được phép trong http tiêu đề giá trị"
Akrikos


2
"Bây giờ, tôi không quá quan tâm đến mã hóa ký tự ... và thành thật mà nói, tôi không thực sự quan tâm quá nhiều đến chúng; tôi chỉ sử dụng UTF-8 một cách mù quáng vì tôi được yêu cầu. :-)" <--- - Liên kết bắt buộc đến joelonsoftware.com/2003/10/08/…
d4nyll

Câu trả lời:


124

Tóm lại: Chỉ ASCII mới được đảm bảo hoạt động. Một số byte không phải ASCII được phép tương thích ngược, nhưng không được phép hiển thị.

HTTPbis đã từ bỏ và chỉ định rằng trong tiêu đề không có mã hóa hữu ích nào ngoài ASCII:

Trước đây, HTTP đã cho phép nội dung trường có văn bản trong bộ ký tự ISO-8859-1 [ISO-8859-1], chỉ hỗ trợ các bộ ký tự khác thông qua việc sử dụng mã hóa [RFC2047]. Trong thực tế, hầu hết các giá trị trường tiêu đề HTTP chỉ sử dụng một tập con của bộ ký tự US-ASCII [USASCII]. Các trường tiêu đề mới được xác định NÊN giới hạn giá trị trường của chúng ở các bộ tám US-ASCII. Người nhận NÊN coi các octet khác trong nội dung trường (obs-text) là dữ liệu không rõ ràng.


Trước đây, RFC 2616 từ năm 1999 đã định nghĩa điều này:

Các từ của * TEXT CÓ THỂ chứa các ký tự từ các bộ ký tự không phải ISO- 8859-1 [22] chỉ khi được mã hóa theo các quy tắc của RFC 2047 [14].

và RFC 2047 là mã hóa MIME , vì vậy nó sẽ là:

=?UTF-8?Q?=E2=9C=B0?=

nhưng tôi không nghĩ rằng nhiều khách hàng (nếu có) ủng hộ nó.


7
Vậy điều đó có ý nghĩa gì? "✰" có hợp lệ / được phép không?
David Murdoch

8
Để mở rộng một chút về một câu trả lời rất hữu ích: "UTF-8" là bộ ký tự và "Q" có nghĩa là giá trị sẽ là "có thể in được trích dẫn". "B" cũng có thể được sử dụng nếu bạn muốn mã hóa giá trị BASE64.
GargantuChet

1
@porneL, Vậy "dữ liệu không rõ ràng" có nghĩa là gì? Có gì chính xác nên người nhận HTTP làm khi nó nhận được những "dữ liệu mờ đục"?
Pacerier

1
@Pacerier "dữ liệu không rõ ràng" có nghĩa là đó là một hộp đen với một loạt các byte mà các ứng dụng không nên cố gắng hiển thị hoặc diễn giải (như dữ liệu nhị phân). Điều gì xảy ra với nó phụ thuộc vào tiêu đề, có thể từ "không có gì" đến "loại bỏ".
Kornel

@Kornel, Btw tại sao bạn lại đổi tên người dùng của mình thành kornel?
Pacerier

10

Vui lòng đọc bình luận trước, câu trả lời này có thể đưa ra kết luận sai từ các nguồn đúng, cần chỉnh sửa.


Bạn có thể sử dụng bất kỳ ký tự ASCII nào có thể in được và không có ký tự đặc biệt nào như ✰ (Không phải là ASCII )

Mẹo : bạn có thể mã hóa bất kỳ thứ gì trong JSON.

Chỉnh sửa : có thể không rõ ràng lúc đầu, mã hóa ký tự được xác định trong tiêu đề chỉ áp dụng cho phần nội dung phản hồi, không áp dụng cho chính tiêu đề. (Vì nó sẽ gây ra vấn đề về gà - & - trứng.)


Tôi muốn tổng hợp tất cả các định nghĩa có liên quan theo thông số được liên kết bởi Penchant.

message-header = field-name ":" [ field-value ]
field-name     = token
field-value    = *( field-content | LWS )

Vì vậy, chúng tôi đang theo đuổi giá trị trường .

LWS            = [CRLF] 1*( SP | HT )
CRLF           = CR LF
CR             = <US-ASCII CR, carriage return (13)>
LF             = <US-ASCII LF, linefeed (10)>
SP             = <US-ASCII SP, space (32)>
HT             = <US-ASCII HT, horizontal-tab (9)>

LWS là viết tắt của Linear White Space. Về cơ bản, LWS là Dấu cách hoặc Tab, nhưng bạn có thể chia giá trị trường của mình thành nhiều dòng bằng cách bắt đầu một dòng mới trước Dấu cách hoặc Tab.

Hãy đơn giản hóa nó thành điều này:

field-value    = <any field-content or Space or Tab>

Bây giờ chúng ta đang theo dõi nội dung trường .

field-content  = <the OCTETs making up the field-value
                 and consisting of either *TEXT or combinations
                 of token, separators, and quoted-string>
OCTET          = <any 8-bit sequence of data>
TEXT           = <any OCTET except CTLs,
                 but including LWS>
CTL            = <any US-ASCII control character
                 (octets 0 - 31) and DEL (127)>
token          = 1*<any CHAR except CTLs or separators>
separators     = "(" | ")" | "<" | ">" | "@"
                 | "," | ";" | ":" | "\" | <">
                 | "/" | "[" | "]" | "?" | "="
                 | "{" | "}" | SP | HT

TEXT là phần tổng quát nhất và bao gồm tất cả phần còn lại - vì vậy hãy quên phần còn lại-. Đây là bộ mã US-ASCII (= ASCII)

Như bạn có thể thấy, tất cả các ký tự ASCII có thể in được đều được phép.


3
Bạn đang mâu thuẫn với những đoạn bạn đã trích dẫn. Tại sao bạn nói "và không có ký tự đặc biệt như ✰"? Các ký tự đặc biệt chỉ là OCTETs và Từ TEXTlà bất kỳ OCTETngoại trừ nào 0 - 31, điều này có nghĩa là tất cả các OCTETký tự từ 32đến 255 đều được phép . Các octet của ✰ là 226, 156176và cả ba trong số họ được cho phép, do đó ✰ được phép theo quy định của đoạn bạn trích dẫn.
Pacerier

2
@Pacerier bạn có vẻ hoàn toàn đúng, tôi không hiểu tại sao tôi lại đưa ra kết luận mà tôi đã làm.
zupa

@Pacerier nhưng tôi chưa sẵn sàng chỉnh sửa nó vì tôi cần kiểm tra kỹ lại thông số kỹ thuật. Tôi e rằng các chi tiết bổ sung đang hạn chế bộ mã US-ASCII, do đó sẽ hỗ trợ cho kết luận nhưng lại khiến suy luận không đủ.
zupa

1
Nói "bạn có thể mã hóa bất cứ thứ gì trong JSON" là một chút sai lầm. JSON cho phép các ký tự Unicode, trong khi tiêu đề HTTP phải là US-ASCII. Các ký tự Unicode sẽ được coi là dữ liệu "không rõ ràng" và do đó hành vi không được xác định bởi đặc tả HTTP. Điều đó đang được nói, JSON có thể được đảm bảo an toàn khi đưa vào tiêu đề HTTP bằng cách thoát các ký tự Unicode thông qua chuỗi thoát \ uXXXX.
Jacob

@zupa, Một vấn đề khác là ... " ngoại trừCTLs " nghĩa là gì? Nó có nghĩa là các ký tự CR, LFđược phép không? Hay nó có nghĩa là chỉ cho phép dãy liên tục " CR LF SP/ HT"? (Nói cách khác, có thể tiêu đề giá trị chứa một đơn CRhoặc LFhoặc HTCan giá trị tiêu đề chứa các ký tự? CR, LFHTtrong bất kỳ thứ tự và số tiền?)
Pacerier
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.