HTTP 414 "İstek URI'si çok uzun" hatasını nasıl çözerim?


103

Bir PHP web uygulaması geliştirdim. Kullanıcıya tek seferde birden fazla sorunu güncelleme seçeneği veriyorum. Bunu yaparken bazen kullanıcı bu hatayla karşılaşıyor. Apache'de URL'nin uzunluğunu artırmanın bir yolu var mı?


Bu hatayı bir Windows sunucusunda ve / veya bir IIS / ASP.NET uygulamasında görüyorsanız şu soruya bakın: stackoverflow.com/q/23237538/12484
Jon Schneider

Yanıtlar:


166

Apache altında sınır, yapılandırılabilir bir değerdir LimitRequestLine. Daha uzun bir istek URI'sini desteklemek istiyorsanız, bu değeri varsayılan 8190 değerinden daha büyük bir değere değiştirin. Değer /etc/apache2/apache2.conf içindedir . Değilse, LimitRequestLine 10000altına yeni bir satır ( ) ekleyin AccessFileName .htaccess.

Ancak, aslında bu sınırla karşılaşıyorsanız, muhtemelen kötüye GETkullanıyorsunuzdur. POSTBu tür verileri iletmek için kullanmalısınız - özellikle değerleri güncellemek için kullandığınızı bile kabul ettiğiniz için. Yukarıdaki bağlantıyı kontrol ederseniz, Apache'nin "Normal koşullar altında, değer varsayılandan değiştirilmemelidir" dediğini bile fark edeceksiniz.


İlk başta POST'u kullanmayı denedim, ancak bu, veritabanında bir güncelleme işlemidir ve orijinal sayfayı o sayfaya gönderilmiş olan değerleri kullanarak yenileyiyorum.
JPro

8
JPro: Bir veritabanını güncellemek, tam olarak kullanmak isteyeceğiniz nedendir POST. POST'u kullanmakla ilgili hiçbir şey, aynı formu yeni gönderilmiş alanlarla doldurmanızı engellemez, bu yüzden bununla ne demek istediğinizden emin değilim.
John Feminella

1
@JPro: Bu durumda olağan teknik, aynı sayfaya POST yapmaktır. Sayfanın işleyicisi (hem GET hem de POST için aynı kod olabilir) önce POST parametrelerini kontrol eder, bulursa bunları ele alır, ardından sayfayı uygun değerlerle doldurarak döndürür, bu da güncellenmiş değerler ( POST ve güncelleme başarılı olursa) veya orijinal değerler (GET ise veya POST ve güncelleme başarısız olursa). Güncelleme başarısız olursa, hatayı açıklayan alan başına hata mesajlarına bile sahip olabilirsiniz.
Mike DeSimone

5
Bunu oldukça geç anladım, bu yüzden paylaşmak isterim. Kelimeyi LimitRequestLinehttpd.conf dosyanızın hiçbir yerinde bulamazsanız, satırı istediğiniz yere kendiniz eklemeniz yeterlidir. Örneğin:LimitRequestLine 100000
Jules Colle

Cevap ve açıklama için teşekkürler, günümü kurtardın. :)
may saghira

16

John'un cevabına göre GET isteğini POST isteği olarak değiştirdim. Sunucu yapılandırmasını değiştirmek zorunda kalmadan çalışır. Ben de bunun nasıl uygulanacağına bakmaya gittim. Aşağıdaki sayfalar yardımcı oldu:

PHP ile jQuery Ajax POST örneği (Yayınlanan verileri temizleme açıklamasına dikkat edin) ve

http://www.openjs.com/articles/ajax_xmlhttp_using_post.php

Temel olarak, fark, GET isteğinin url ve parametrelere bir dizede sahip olması ve ardından null göndermesidir:

http.open("GET", url+"?"+params, true);
http.send(null);

POST isteği url'yi ve parametreleri ayrı komutlarda gönderirken:

http.open("POST", url, true);
http.send(params);

İşte çalışan bir örnek:

ajaxPOST.html:

<html>
<head>
<script type="text/javascript">
    function ajaxPOSTTest() {
        try {
            // Opera 8.0+, Firefox, Safari
            ajaxPOSTTestRequest = new XMLHttpRequest();
        } catch (e) {
            // Internet Explorer Browsers
            try {
                ajaxPOSTTestRequest = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    ajaxPOSTTestRequest = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                    // Something went wrong
                    alert("Your browser broke!");
                    return false;
                }
            }
        }

        ajaxPOSTTestRequest.onreadystatechange = ajaxCalled_POSTTest;
        var url = "ajaxPOST.php";
        var params = "lorem=ipsum&name=binny";
        ajaxPOSTTestRequest.open("POST", url, true);
        ajaxPOSTTestRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        ajaxPOSTTestRequest.send(params);
    }

    //Create a function that will receive data sent from the server
    function ajaxCalled_POSTTest() {
        if (ajaxPOSTTestRequest.readyState == 4) {
            document.getElementById("output").innerHTML = ajaxPOSTTestRequest.responseText;
        }
    }
</script>

</head>
<body>
    <button onclick="ajaxPOSTTest()">ajax POST Test</button>
    <div id="output"></div>
</body>
</html>

ajaxPOST.php:

<?php

$lorem=$_POST['lorem'];
print $lorem.'<br>';

?>

12.000'den fazla karakteri sorunsuz bir şekilde gönderdim.


4

Basit bir çözümüm var.

URI'nizin stringdataçok uzun bir dizeye sahip olduğunu varsayalım . Sunucunuzun sınırlarına bağlı olarak onu basitçe birkaç parçaya ayırabilirsiniz. Sonra benim durumumda bir dosya yazmak için ilkini gönderin. Ardından, daha önce eklenen verilere eklemek için sonrakileri gönderin.


Bir örnek verebilir misiniz? Kullanıcı tarafından oluşturulduğunda dizeyi nasıl böldüğünüzü görebiliyorum ...
endyourif

4
Çok ucuz çözüm. Alan sorununu yeniden düşünmek daha iyidir!
Muhammad Hewedy

13
Bu, çok fazla olumsuz oyu hak etmiyor. Birden fazla istek göndermenin kabul edilebilir bir geçici çözüm olabileceği durumlar vardır. Doğru, cevabın kalitesi biraz düşük, ancak bu, SO'da yepyeni bir kullanıcıdan beklenmelidir. Henüz "SO anlamayan" yeni gelenleri olumsuz oylamak yerine biraz sevgi gösterelim ve geri bildirimde bulunalım!
rinogo

1
Katılıyorum, uygulanabilir görünüyor
Felipe Valdes

3

JQuery'den $ .getJSON () kullandıktan sonra bu hatayı aldım. Göndermek için yeni değiştirdim:

data = getDataObjectByForm(form);
var jqxhr = $.post(url, data, function(){}, 'json')
    .done(function (response) {
        if (response instanceof Object)
            var json = response;
        else
            var json = $.parseJSON(response);
        // console.log(response);
        // console.log(json);
        jsonToDom(json);
        if (json.reload != undefined && json.reload)
            location.reload();
        $("body").delay(1000).css("cursor", "default");
    })
    .fail(function (jqxhr, textStatus, error) {
        var err = textStatus + ", " + error;
        console.log("Request Failed: " + err);
        alert("Fehler!");
    });

2
bu bir cevap mı yoksa soru mu?
Takarii

Bu iyi bir hızlı çözümdür. Almadan postaya geçiş, herhangi bir sunucu yapılandırması değişikliği olmadan uzun URL'ye izin verir.
mt025

1

RFC 2616'dan bir alıntı : Köprü Metni Aktarım Protokolü - HTTP / 1.1 :

POST yöntemi kökenli sunucu İsteği-Line Request-URI tarafından tanımlanan kaynağın yeni bir ikincil parçası olarak isteğe eklenmiş varlığa kabul etmesini talep etmek için kullanılır. POST, tek tip bir yöntemin aşağıdaki işlevleri kapsamasına izin verecek şekilde tasarlanmıştır:

  • Mevcut kaynakların ek açıklaması;
  • Bir ilan tahtasına, haber grubuna, posta listesine veya benzer bir makale grubuna mesaj göndermek;
  • Bir veri işleme sürecine bir form göndermenin sonucu gibi bir veri bloğu sağlamak ;
  • Ekleme işlemiyle bir veritabanını genişletme.

8
Bunun soruyu nasıl yanıtladığını görmüyor musunuz ..?
Afr

Orijinal gönderen, kayıtların güncellenmekte olduğunu söyledi. Güncellemeler için GET yerine POST veya PUT kullanmak iyi bir uygulamadır. Ancak, tabii ki, güncelleme öncesinde görüntülenecek kayıtlar alınırken maksimum URL sınırı aşılıyor olabilir ve ardından GET yöntemi uygundur, ancak bu sınır nedeniyle başarısız olabilir. Orijinal poster, sorunun hangi aşamada ortaya çıktığından bahsetmedi, bu nedenle güncellemenin kendisi sırasında olduğu varsayılabilir, ancak emin
olamayız
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.