Pengkodean karakter apa yang harus saya gunakan untuk header HTTP?

122

Saya menggunakan karakter khusus HTML (✰) yang "menyenangkan" (lihat http://html5boilerplate.com/ untuk info lebih lanjut) untuk ServerHTTP-header dan saya bertanya-tanya apakah itu "diizinkan" per spesifikasi.

  • Menggunakan Tab Jaringan di alat dev di Chrome pada Windows Xp Pro SP 3 Saya melihat ✰ baik-baik saja.

  • Di IE8, ✰ tidak ditampilkan dengan benar.

  • Validator HTML w3.org tidak merendernya dengan benar ( â°malah menampilkan " ").

Sekarang, saya tidak terlalu tertarik pada pengkodean karakter ... dan terus terang saya tidak terlalu peduli tentang mereka; Saya hanya menggunakan UTF-8 secara membabi buta karena saya disuruh. :-)


Apakah perbedaan ini disebabkan oleh bug di parser / browser / mesin / (apa pun namanya) yang berbeda?

Apakah ada spesifikasi untuk ini atau mungkin daftar karakter yang diizinkan untuk "nilai" header HTTP?

David Murdoch
sumber
29
Pertanyaan ini akan jauh lebih baik jika ditanyakan secara umum: "Karakter mana yang diizinkan dalam nilai header http"
Akrikos
2
"Sekarang, saya tidak terlalu tertarik pada pengkodean karakter ... dan terus terang saya tidak terlalu peduli tentang mereka; Saya hanya menggunakan UTF-8 secara membabi buta karena saya disuruh. :-)" <--- - Tautan wajib ke joelonsoftware.com/2003/10/08/…
d4nyll

Jawaban:

124

Singkatnya: Hanya ASCII yang dijamin dapat berfungsi. Beberapa byte non-ASCII diizinkan untuk kompatibilitas mundur, tetapi tidak seharusnya dapat ditampilkan.

HTTPbis menyerah dan menetapkan bahwa di header tidak ada pengkodean yang berguna selain ASCII:

Secara historis, HTTP telah mengizinkan konten bidang dengan teks dalam rangkaian karakter ISO-8859-1 [ISO-8859-1], mendukung rangkaian karakter lain hanya melalui penggunaan enkode [RFC2047]. Dalam praktiknya, sebagian besar nilai kolom header HTTP hanya menggunakan subset dari charset US-ASCII [USASCII]. Bidang tajuk yang baru ditetapkan HARUS membatasi nilai bidangnya menjadi oktet US-ASCII. Penerima HARUS memperlakukan oktet lain dalam konten bidang (teks-obs) sebagai data buram.


Sebelumnya, RFC 2616 dari 1999 mendefinisikan ini:

Kata-kata * TEXT MUNGKIN berisi karakter dari kumpulan karakter selain ISO- 8859-1 [22] hanya jika dikodekan sesuai dengan aturan RFC 2047 [14].

dan RFC 2047 adalah pengkodean MIME , jadi ini akan menjadi:

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

tetapi menurut saya tidak banyak (jika ada) klien yang mendukungnya.

Kornel
sumber
7
jadi apa maksudnya itu? Apakah "✰" valid / diperbolehkan?
David Murdoch
8
Untuk memperluas sedikit jawaban yang sangat berguna: "UTF-8" adalah himpunan karakter, dan "Q" berarti nilainya akan menjadi "quote-printable". "B" juga dapat digunakan jika Anda ingin mengenkode nilai BASE64.
GargantuChet
1
@porneL, Jadi apa artinya "data buram"? Apa yang sebenarnya harus dilakukan penerima HTTP saat menerima "data buram" ini?
Pacerier
1
@Pacerier "data buram" berarti ini adalah kotak hitam dengan sekumpulan byte yang tidak boleh coba ditampilkan atau ditafsirkan oleh aplikasi (seperti data biner). Apa yang terjadi dengan itu tergantung pada header, mungkin berkisar dari "tidak ada" hingga "membuang".
Kornel
@Kornel, Btw kenapa kamu ganti username jadi kornel?
Pacerier
10

Silakan baca komentar terlebih dahulu, jawaban ini sepertinya menarik kesimpulan yang salah dari sumber yang benar, perlu diedit.


Anda dapat menggunakan karakter ASCII yang dapat dicetak, dan tidak ada karakter khusus seperti ✰ (Yang bukan ASCII )

Tip : Anda dapat mengenkode apa saja di JSON.

Sunting : mungkin tidak terlihat jelas pada awalnya, pengkodean karakter yang ditentukan di tajuk hanya berlaku untuk isi respons, bukan untuk tajuk itu sendiri. (Karena itu akan menyebabkan masalah ayam - & - telur.)


Saya ingin merangkum semua definisi yang relevan sesuai spesifikasi yang ditautkan oleh Penchant.

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

Jadi, kami mengejar nilai bidang .

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 adalah singkatan dari Linear White Space. Pada dasarnya, LWS adalah Spasi atau Tab, tetapi Anda dapat memecah nilai bidang Anda menjadi beberapa baris dengan memulai baris baru sebelum Spasi atau Tab.

Mari kita sederhanakan menjadi ini:

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

Sekarang kita mengejar konten lapangan .

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 adalah yang paling umum dan mencakup yang lainnya -jadi lupakan yang lainnya-. Berikut adalah charset US-ASCII (= ASCII)

Seperti yang Anda lihat, semua karakter ASCII yang dapat dicetak diizinkan.

zupa
sumber
3
Anda bertentangan dengan bagian yang Anda kutip. Mengapa Anda mengatakan "dan tidak ada karakter khusus seperti ✰"? Karakter khusus hanyalah OCTETs, dan Because TEXTadalah salah satu OCTETkecuali 0 - 31, ini berarti semua OCTETs dari 32hingga 255 diperbolehkan . Oktet ✰ adalah 226,, 156dan 176ketiganya diperbolehkan, oleh karena itu ✰ diperbolehkan sesuai dengan kutipan yang Anda kutip.
Pacerier
2
@Pacerier Anda tampak sepenuhnya benar, saya tidak mengerti mengapa saya menarik kesimpulan yang saya lakukan.
zupa
@Pacerier namun saya belum siap untuk mengeditnya karena saya perlu memeriksa ulang spesifikasinya lagi. Saya khawatir detail tambahan membatasi rangkaian karakter US-ASCII yang pada gilirannya akan mendukung kesimpulan namun membuat alasannya tidak memadai.
zupa
1
Mengatakan "Anda dapat mengenkode apa pun di JSON" agak menyesatkan. JSON mengizinkan karakter Unicode, sedangkan header HTTP harus US-ASCII. Karakter unicode akan diperlakukan sebagai data "buram" dan karenanya perilakunya tidak ditentukan oleh spesifikasi HTTP. Karena itu, JSON dapat dibuat aman untuk disertakan dalam header HTTP dengan meng-escape karakter Unicode melalui \ uXXXX escape sequence.
Jacob
@zupa, Masalah lainnya adalah ... apa artinya " kecualiCTLs "? Apakah itu berarti karakter CR, LFdiperbolehkan? Atau apakah itu berarti hanya urutan kontinu " CR LF SP/ HT" yang diperbolehkan? (Dengan kata lain, dapat sundulan nilai mengandung satu CRatau LFatau HTCan nilai sundulan berisi karakter? CR, LF, Dan HTdalam urutan dan jumlah?)
Pacerier