Neden HTTP'de POST yönlendirmesi yok?


162

HTTP yönlendirmeleri, HTTP 301 ve 302 kodları (belki de diğer kodlar) ve gidilecek yeni yerin adresini içeren "Konum" olarak bilinen bir başlık alanı aracılığıyla yapılır. Ancak, tarayıcılar her zaman bu URL’ye bir "GET" isteği gönderir.

Ancak, POST (örneğin, banka ödemeleri) aracılığıyla birçok kez kullanıcılarınızı başka bir alana yönlendirmeniz gerekir. Bu ortak bir senaryodur ve gerçekten bir gerekliliktir. HTTP şartnamesinde bu kadar yaygın bir gereksinimin neden ihmal edildiğini bilen var mı? Çözüm, eylemi hedef konuma ( Konum başlık alanının değeri) ayarlanmış bir form (gizli alanlardaki parametrelerle ) setTimeoutgöndermek ve formu hedef konuma göndermek için kullanmaktır .


1
307 durum kodu aradığınızı mı? Aşağıdaki cevaba bakınız.
David Ruttka,

Yanıtlar:


180

HTTP 1.1'de aslında, aynı yöntem kullanılarak ve veri sonrası isteğin tekrarlanması gerektiğini belirten bir durum kodu ( 307 ) vardır .

Diğerlerinin de söylediği gibi, burada kötüye kullanım potansiyeli vardır, bu yüzden birçok çerçeve soyutlamalarında 301 ve 302'ye yapışabilir. Bununla birlikte, doğru bir anlayış ve sorumlu bir kullanımla aradığınızı başarabilmelisiniz.

W3.org şartnamesine göre , kullanıcı söz konusu METHODolduğunda HEADveya olmadığında GET, kullanıcı temsilcilerinin isteği yeni lokasyonda tekrar yerine getirmeden önce kullanıcıyı uyarması gerektiğini unutmayın . Eski kullanıcı temsilcilerinin 307 ile ne yapacaklarından emin olmadıklarında, kullanıcı için ayrıca bir not ve geri dönüş mekanizması sağlamalısınız .

Bu formu kullanarak:

<form action="Test307.aspx" method="post">
    <input type="hidden" name="test" value="the test" />
    <input type="submit" value="test" />    
</form>

Ve Test307.aspx'e Konum ile birlikte 307 döndürmeniz yeterlidir: http://google.com , Chrome 13 ve Fiddler "test = test" in gerçekten Google’a gönderildiğini onaylar. Elbette, Google'ın POST'a izin vermediğinden sonraki yanıt 405'tir ancak mekaniği gösterir.

Daha fazla bilgi için bkz . HTTP durum kodlarının listesi ve W3.org spec .

307 Geçici Yönlendirme (HTTP / 1.1'den beri) Bu durumda, istek başka bir URI ile tekrarlanmalıdır, ancak gelecekteki istekler hala orijinal URI'yi kullanabilir. 2 303'ün aksine, orijinal istek yeniden gönderilirken, istek yöntemi değiştirilmemelidir. Örneğin, bir POST isteğinin başka bir POST isteği kullanılarak tekrarlanması gerekir.


2
@DavidRuttka, Vahşi doğada tarayıcı desteği nedir ?
Pacerier

5
@DavidRuttka, rfc7231'i hesaba katarak cevabınızı güncellemek isteyebilirsiniz (eski rfc2616). Kullanıcıdan bilgi istemek, rfc2616'daki bir gereksinime dayanmaktadır. Bu gereklilik rfc7231'e düşürülür ve rfc7231 ayrıca 307 yönlendirmelerinin istek yöntemini değiştirmemesi şartını da getirir (alıntıda cevabınızın sonundan bahsedersiniz).
nibarius

Tools.ietf.org/id/draft-hunt-http-rest-redirect-00.html "e göre 301-306 HTTP yönlendirme kodları servis sağlayıcısının müşterinin bir kullanıcı olduğunun farkında olmadığı sürece kullanılmamalıdır. ajan "Öyle görünüyor ki ReSTful hizmetleri 301 yerine 308 kullanmalı. Ancak bu sadece bir taslak.
Bruce Adams,

49

Burada bu sayfada iyi bir açıklama buldum .

WWW’daki en basit durumlar “önemsiz” işlemlerdir, yani herhangi bir zarar vermeden tekrarlanabilen işlemler. Bunlar, genellikle basit URL referanslarını aldıkları (örneğin, href = veya src = HTML'deki öznitelikler) veya GET yöntemini kullanarak form gönderimleri oldukları için "GET" işlemleridir. Bu tür bir işlemi yönlendirmek basittir ve hiçbir soru sorulmaz: müşteri, bir URL: yeni URL'yi belirten bir başlık dahil olmak üzere yeniden yönlendirme yanıtını alır ve müşteri işlemi yeni URL'ye yeniden vererek yanıt verir. Bu yeniden yönlendirmelerle ilişkilendirilen farklı 30x durum kodları arasında örtülü önbelleklenebilirliklerinde bir fark vardır, ancak aksi takdirde GET isteklerine yanıt olarak temelde benzerdir (301 ve 302).

POST işlemleri farklıdır, çünkü prensipte belirsizdir (pizza sipariş etmek, oy kullanmak ya da her neyse) ve bunların keyfi bir şekilde tekrarlanmaması gerekir.

HTTP protokolü spesifikasyonları bu ayrımı göz önünde bulundurmak için tasarlanmıştır: GET metodu doğal olarak iddiasız olarak tanımlanırken, POST metodu en azından potansiyel olarak idrarsız olan olarak tanımlanır; şartnameler, kullanıcıları istemeden istemeyecek bir şekilde korumak için müşteri temsilcileri (tarayıcılar gibi) tarafından alınacak bir dizi önlemi gerektirir; .

Kullanıcıları teknik olarak istenmeyen kargaşaya neden olmalarını veya uygulamalarına istenmeyen zarar vermelerini önlemek için teknik olarak kısıtlama hayranı olmasam da, konuyu anlayabiliyorum ve mantıklı geliyor.


akıl yürütmenin büyük kısmı, intertüplerin yavaş ve güvenilmez oldukları günlere gider (ki bunlar hala dünyanın birçok yerindedir). Çevirmeli bağlantıyı ne zaman kullandığımı ve başka birisinin telefonu aldığında rasgele bağlantısının kesileceğini açıkça hatırlıyorum. Sayfayı yeniden yüklemek ve sunucunun hangi durumda olduğunu görmek ve işleri yeniden göndermek ve aynı işlemi iki kez gerçekleştirme riskini almaktan daha iyiydi.
zzzzBov

@Falcon, "ziyaretçi sayacını" arttırmak iddiasız sayılır mı? Öyleyse, bugünlerde neredeyse hiç web sitesi anlamsız GET'ler yapmaz ...
Pacerier

@Pacerier: Normalde idempotent, "iki anlamlı ziyaretten değil, aynı ürünü iki kez satın alarak," anlamlı bir şekilde idempotent "olarak yorumlanır. Aksi takdirde, oldukça haklısın. Ancak gerçekte, teknik özellik, sunucuların, kopyaları önlemek için sayfaya bir kimlik eklemek gibi, gerektiğinde anlamsız olmalarını gerektirmiştir - tarayıcının, kullanıcıya herhangi bir doğrulukla cevap verebilecekleri bir soru sormasını istememektedir. Ne olursa olsun, bir POST yönlendirmesini engellemek bağımsızlığı etkilemez; bu sadece isteğin hedefinin gerçekten orada olduğunu söyleyen bir mesaj.
Lawrence Dol

Bunun, bu akıl yürütme için nasıl bir anlam ifade ettiğini anlamıyorum. Chase banka web sitesinde olduğumu ve bir form gönderdiğimi söyleyin. Onları çoktan kabul ettim / güvendim. Dolayısıyla, bu verileri başka bir sayfaya yönlendirmeleri gerekiyorsa, neden tekrar aynı fikirdeyim ki? Ya da başka bir örnek olarak, JavaScript'i varsayılan olarak kapatan bir insan olduğumu söyleyin. Bir gün online olarak bir ipotek başvurusu doldurmaya gidiyorum ve formu teslim ettiğimde hataları var. Uygulamanın verileri önceden doldurmak için henüz doldurduğum sayfaya (POST ile) yeniden yönlendirebilmesi harika olurdu.
b01

@Flacon, POST ile yönlendirmeyi kısıtlamanın herhangi bir konuda kargaşayı önleyebileceğinin kanıtına ihtiyacım var. Uygulamaya verilerimle güvenmem gerektiğinden, verilerle birlikte istedikleri zaman istediklerini yapabilirler. Üstelik yönlendirmelerin POST isteğinden daha savunmasız olduğunu düşünmüyorum.
b01

3

GET (ve diğer birkaç yöntem) http spec ( RFC 2616 ) 'de' GÜVENLİ 'olarak tanımlanır :

9.1.1 Güvenli Yöntemler

Uygulayıcılar, yazılımın kullanıcıyı İnternet üzerindeki etkileşimlerinde temsil ettiğinin farkında olmalı ve kullanıcının kendileri ya da başkaları için beklenmeyen bir öneme sahip olabilecek her türlü eylemden haberdar olmalarına dikkat etmelidir.

Özellikle, GET ve HEAD yöntemlerinin geri alım dışında bir işlem yapmanın önemine sahip OLMAMASI gerektiği anlaşılmıştır. Bu yöntemlerin "güvenli" olduğu düşünülmelidir. Bu, kullanıcı temsilcilerinin POST, PUT ve DELETE gibi diğer yöntemleri özel bir şekilde temsil etmelerine izin verir, böylece kullanıcının olası bir güvensiz eylem istendiği gerçeğinin farkına varır.

Doğal olarak, bir GET isteğinin gerçekleştirilmesinin bir sonucu olarak sunucunun yan etkiler oluşturmadığından emin olmak mümkün değildir; Aslında, bazı dinamik kaynaklar bir özellik olarak düşünür. Buradaki önemli ayrım, kullanıcının yan etkileri talep etmemesidir, bu nedenle bunlar için hesap verilemez.

Bu, bir GET isteğinin, görmek istemedikleri bir şeyi görmenin ötesinde, kullanıcı için hiçbir zaman ciddi bir sonucu olmayacağı anlamına gelir; ancak bir POST isteği, kendileri veya başkaları için önemli olan bir kaynağı değiştirebilir.

Bu, JavaScript ile değişmiş olmasına rağmen, geleneksel olarak farklı kullanıcı arayüzleri vardı - kullanıcılar, bağlantıları tıklayarak GET isteklerini tetikleyebilir, ancak bir POST isteğini tetiklemek için bir form doldurmaları gerekirdi. HTTP tasarımcılarının güvenli ve güvenli olmayan yöntemler arasındaki ayrımı sürdürmek konusunda istekli olduklarını düşünüyorum.

Ayrıca bir POST'a yönlendirmenin gerekli olması gerektiğini de sanmıyorum. Gerçekleştirilmesi gereken herhangi bir işlem, muhtemelen sunucu yan kodu içindeki bir işlev çağrılarak veya farklı bir sunucuda gerçekleşmesi gerekiyorsa, tarayıcıya POST için bir URL içeren bir yönlendirme göndermek yerine, sunucuya gerçekleştirilebilir. Kullanıcı için bir vekil gibi davranarak o sunucunun kendisine bir istek yapabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.