Apa fungsi dari header HTTP "Vary: Accept"?

93

Saya menggunakan PHP untuk menghasilkan halaman web dinamis. Seperti yang dinyatakan pada tutorial berikut (lihat tautan di bawah), tipe MIME dari dokumen XHTML harus "application / xhtml + xml" jika $ _SERVER ['HTTP_ACCEPT'] mengizinkannya. Karena Anda dapat menyajikan halaman yang sama dengan 2 MIME yang berbeda ("application / xhtml + xml" dan "text / html"), Anda harus menyetel header HTTP "Vary" ke "Accept". Ini akan membantu cache pada proxy.

Tautan: http://keystonewebsites.com/articles/mime_type.php

Sekarang saya tidak yakin dengan implikasi dari: header ('Vary: Accept'); Saya tidak begitu yakin tentang apa tepatnya 'Vary: Accept' akan lakukan ...

Satu-satunya penjelasan yang saya temukan adalah:

Setelah header Jenis Konten, header Vary dikirim ke (jika saya memahaminya dengan benar) memberi tahu cache perantara, seperti server proxy, bahwa jenis konten dokumen bervariasi tergantung pada kemampuan klien yang meminta dokumen. http://www.456bereastreet.com/archive/200408/content_negotiation/

Siapa pun dapat memberi saya penjelasan "nyata" tentang tajuk ini ( dengan nilai tersebut ). Saya rasa saya memahami hal-hal seperti: Bervariasi: Terima-Enkode di mana cache pada proxy dapat didasarkan pada pengkodean laman yang ditayangkan, tetapi saya tidak mengerti: Bervariasi: Terima

AlexV
sumber
1
Terus terang - jangan repot-repot. Mengesampingkan kekurangan dalam penerapan di situs itu, satu-satunya saat Anda akan mendapatkan manfaat dari penyajian dengan tipe konten XML adalah ketika Anda melakukan hal-hal yang tidak dapat dilakukan dalam teks / html - dan jika semua yang Anda lakukan adalah mengganti Doctype dan xmlns, maka Anda tidak akan melakukan hal-hal itu. Tetap gunakan teks / html. Untuk masalah ini, Anda sebaiknya tetap menggunakan HTML 4.01.
Quentin
Ya, saya mengerti ini dan saya pikir "masalah" seperti ini terlalu sering muncul dalam pengembangan Web. Berkat "harus" dalam spesifikasi / RFC!
AlexV
2
Anda mungkin harus membaca ini: blogs.msdn.com/ieinternals/archive/2009/06/17/… sebelum mempertimbangkan untuk menggunakan VARY.
EricLaw
1
Video ini memiliki penjelasan yang bagus tentang Vary:header.
Kannan Mohan

Jawaban:

94
  • The cache-controlHeader adalah mekanisme utama untuk server HTTP untuk memberitahu proxy caching yang "kesegaran" dari tanggapan. (yaitu, bagaimana / jika lama menyimpan respons di cache)

  • Dalam beberapa situasi, cache-controlarahan tidak cukup. Diskusi dari kelompok kerja HTTP diarsipkan di sini, menjelaskan halaman yang hanya berubah dengan bahasa. Ini bukan kasus penggunaan yang benar untuk berbagai header, tetapi konteksnya berharga untuk diskusi kita. (Meskipun saya yakin header Vary akan menyelesaikan masalah dalam kasus itu, ada Cara yang Lebih Baik.) Dari halaman itu:

Vary hanya untuk kasus-kasus di mana tidak ada harapan atau terlalu rumit bagi proxy untuk meniru apa yang akan dilakukan server.

Contoh yang dibuat-buat:

Server HTTP Anda memiliki halaman landing yang besar. Anda memiliki dua halaman yang sedikit berbeda dengan URL yang sama, tergantung apakah pengguna pernah ke sana sebelumnya. Anda membedakan antara permintaan dan "jumlah kunjungan" pengguna berdasarkan Cookie. Tetapi - karena laman landas server Anda sangat besar, Anda ingin proxy perantara menyimpan respons dalam cache jika memungkinkan.

Header URL, Last-Modified dan Cache-Control tidak cukup untuk memberikan wawasan ini ke proxy cache, tetapi jika Anda menambahkan Vary: Cookie, mesin cache akan menambahkan header Cookie ke keputusan cache-nya.

Akhirnya, untuk lalu lintas kecil, situs web dinamis - Saya selalu menemukan yang sederhana Cache-Control: no-cache, no-storedan Pragma: no-cachememadai.

Edit - untuk menjawab pertanyaan Anda dengan lebih tepat: header permintaan HTTP 'Terima' menentukan Jenis Konten yang dapat diproses klien. Jika Anda memiliki dua salinan dari konten yang sama di URL yang sama, hanya berbeda dalam Jenis Konten, maka penggunaan Vary: Acceptmungkin sesuai.

Perbarui 11 Sep 12:

Saya menyertakan beberapa tautan yang muncul di komentar sejak komentar ini pertama kali dikirim. Keduanya adalah sumber yang sangat baik untuk contoh dunia nyata (dan masalah) dengan Vary: Terima; Jika Anda membaca jawaban ini, Anda perlu membaca tautan itu juga.

Yang pertama, dari EricLaw yang luar biasa, tentang perilaku Internet Explorer dengan header Vary dan beberapa tantangan yang dihadirkannya kepada pengembang: Vary Header Mencegah Caching di IE . Singkatnya, IE (pra IE9) tidak menyimpan konten apa pun yang menggunakan header Vary karena cache permintaan tidak menyertakan header Permintaan HTTP. EricLaw (Eric Lawrence di dunia nyata) adalah Manajer Program di tim IE.

Yang kedua adalah dari Eran Medan, dan merupakan diskusi yang sedang berlangsung tentang perilaku tak terduga terkait Vary di Chrome: Backing tidak menangani header Vary dengan benar . Ini terkait dengan perilaku IE, kecuali pengembang Chrome mengambil pendekatan yang berbeda - meskipun tampaknya itu bukan pilihan yang disengaja.

JJ
sumber
3
Waspadalah terhadap ini sehubungan dengan tombol browser kembali di Chrome, ada semacam perang api pada bug ini (yang sekarang tidak akan diperbaiki karena beberapa alasan) code.google.com/p/chromium/issues/detail?id=94369
Eran Medan
6
@EranMedan Bug Chrome telah diperbaiki.
59

Vary: Accepthanya mengatakan bahwa respons dibuat berdasarkan Acceptheader dalam permintaan. Permintaan dengan Accepttajuk berbeda mungkin mendapatkan respons yang berbeda.

(Anda dapat melihat bahwa kode PHP tertaut terlihat $HTTP_ACCEPT. Itulah nilai dari Acceptheader permintaan.)

Untuk cache HTTP, ini berarti respons harus di-cache dengan sangat hati-hati. Ini hanya akan menjadi pertandingan yang valid untuk permintaan selanjutnya dengan Acceptheader yang persis sama .

Sekarang ini hanya penting jika halaman tersebut dapat disimpan dalam cache. Secara default, halaman PHP tidak. Halaman PHP dapat menandai keluaran sebagai dapat disimpan dalam cache dengan mengirimkan header tertentu ( Expires, misalnya). Tetapi apakah dan bagaimana melakukannya adalah pertanyaan yang berbeda.

Jason Orendorff
sumber
apakah itu "mungkin mendapatkan" atau "seharusnya mendapatkan"?
Pacerier
6
@Pacerier "mungkin mendapatkan" benar. Vary: Accepttidak berarti bahwa setiap kemungkinan Acceptnilai tajuk yang berbeda menghasilkan respons yang berbeda dan unik. Ini hanya berarti bahwa Accepttajuk yang berbeda dapat menghasilkan respons yang berbeda.
Jason Orendorff
2

Sebenarnya ada sejumlah besar fitur baru yang segera hadir (dan sudah ada di Chrome) yang membuat Varytajuk sangat berguna. Misalnya, pertimbangkan Petunjuk Klien . Ketika digunakan sehubungan dengan gambar, misalnya, petunjuk klien memungkinkan server untuk mengoptimalkan sumber daya seperti gambar bergantung pada:

  • lebar gambar
  • Lebar Area Pandang
  • Jenis pengkodean yang didukung oleh browser (pikirkan WebP)
  • Downlink (pada dasarnya kecepatan jaringan)

Jadi server yang mendukung fitur tersebut akan mengatur Varyheader untuk menunjukkannya.

Chrome mengiklankan dukungan WebP dengan menyetel "image / webp" sebagai bagian dari Varytajuk untuk setiap permintaan. Jadi server mungkin menulis ulang gambar sebagai WebP jika browser mendukungnya, jadi proxy perlu memeriksa header agar tidak menyimpan gambar WebP dan kemudian menyajikannya ke browser yang tidak mendukung WebP. Jelas, jika server Anda tidak melakukan itu, itu tidak masalah. Jadi karena respons server bervariasi pada Acceptheader permintaan, respons harus menyertakannya agar tidak membingungkan proxy:

Vary: Accept

Contoh lain mungkin adalah lebar gambar. Pada peramban seluler, Widthtajuk mungkin cukup kecil untuk gambar responsif, dibandingkan dengan tampilannya jika dilihat dari peramban desktop. Jadi dalam hal Widthitu akan ditambahkan ke Varyheader sangat penting untuk proxy untuk tidak cache versi seluler kecil dan menyajikannya ke browser desktop, atau sebaliknya. Dalam hal ini, tajuk mungkin termasuk:

Vary: Accept, Width

Atau jika server mendukung semua spesifikasi petunjuk klien, header akan menjadi seperti ini:

Vary: Accept, DPR, Width, Save-Data, Downlink
Brad Berger
sumber