Jak rozwiązać błąd HTTP 414 „Za długi identyfikator URI żądania”?


103

Stworzyłem aplikację internetową w języku PHP. Daję użytkownikowi możliwość aktualizacji wielu problemów za jednym razem. Robiąc to, czasami użytkownik napotyka ten błąd. Czy istnieje sposób na zwiększenie długości adresu URL w Apache?


Jeśli widzisz ten błąd na serwerze Windows i / lub w aplikacji IIS / ASP.NET, zobacz pytanie: stackoverflow.com/q/23237538/12484
Jon Schneider

Odpowiedzi:


166

Pod Apache, limit jest wartością konfigurowalny LimitRequestLine. Zmień tę wartość na większą niż domyślna 8190, jeśli chcesz obsługiwać dłuższy identyfikator URI żądania. Wartość znajduje się w /etc/apache2/apache2.conf . Jeśli nie, dodaj nową linię ( LimitRequestLine 10000) pod AccessFileName .htaccess.

Pamiętaj jednak, że jeśli faktycznie osiągasz ten limit, prawdopodobnie GETna początku nadużywasz . Powinieneś używać POSTdo przesyłania tego rodzaju danych - zwłaszcza, że ​​nawet przyznajesz, że używasz ich do aktualizowania wartości. Jeśli zaznaczysz powyższy link, zauważysz, że Apache mówi nawet „W normalnych warunkach wartość nie powinna być zmieniana z domyślnej”.


Na początku próbowałem użyć POST, ale jest to operacja aktualizacji bazy danych i odświeżam oryginalną stronę przy użyciu wartości, które zostały pierwotnie opublikowane na tej stronie.
JPro

8
JPro: Aktualizacja bazy danych jest mniej więcej dokładnym powodem, dla którego byś użył POST. Nic w używaniu POST nie wyklucza wypełnienia tego samego formularza polami, które właśnie zostały wysłane, więc nie jestem pewien, co przez to rozumiesz.
John Feminella

1
@JPro: Zwykłą techniką w tym przypadku jest POST na tej samej stronie. Procedura obsługi strony (która może być tym samym kodem zarówno dla GET, jak i POST) najpierw sprawdza parametry POST, obsługuje je, jeśli je znajdzie, a następnie zwraca stronę z wypełnionymi odpowiednimi wartościami, które będą albo zaktualizowanymi wartościami ( jeśli POST i aktualizacja powiedzie się) lub oryginalne wartości (jeśli GET lub POST i aktualizacja się nie powiedzie). Jeśli aktualizacja się nie powiedzie, możesz nawet wyświetlić komunikaty o błędach dla poszczególnych pól opisujące awarię.
Mike DeSimone

5
Zrozumiałem to dość późno, więc chciałbym się tym podzielić. Jeśli nie możesz znaleźć tego słowa LimitRequestLinew swoim pliku httpd.conf, po prostu dodaj tę linię w dowolnym miejscu. Na przykład:LimitRequestLine 100000
Jules Colle

dzięki za odpowiedź i wyjaśnienie, uratowałeś mi dzień. :)
saghira

16

Na podstawie odpowiedzi Johna zmieniłem żądanie GET na żądanie POST. Działa bez konieczności zmiany konfiguracji serwera. Zacząłem więc szukać, jak to zaimplementować. Pomocne były następujące strony:

Przykład jQuery Ajax POST z PHP (zwróć uwagę na uwagę dotyczącą czyszczenia opublikowanych danych) i

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

Zasadniczo różnica polega na tym, że żądanie GET ma adres URL i parametry w jednym ciągu, a następnie wysyła wartość null:

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

podczas gdy żądanie POST wysyła adres URL i parametry w oddzielnych poleceniach:

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

Oto działający przykład:

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>';

?>

Właśnie wysłałem ponad 12 000 znaków bez żadnych problemów.


4

Mam proste obejście.

Załóżmy, że Twój identyfikator URI zawiera stringdatazbyt długi ciąg . Możesz po prostu podzielić go na kilka części w zależności od ograniczeń serwera. Następnie prześlij pierwszy, w moim przypadku do napisania pliku. Następnie prześlij kolejne, aby dołączyć do wcześniej dodanych danych.


Czy możesz podać przykład? Widzę, jak dzielisz ciąg, gdy jest on wygenerowany przez użytkownika ...
endyourif

4
Bardzo tanie obejście. Lepiej przemyśleć problem domeny!
Muhammad Hewedy

13
To nie zasługuje na tak wiele głosów przeciw. Z pewnością istnieją sytuacje, w których przesłanie wielu wniosków może być akceptowalnym obejściem. To prawda, że ​​jakość odpowiedzi jest nieco niska, ale można się tego spodziewać po zupełnie nowym użytkowniku SO. Okażmy trochę miłości i podzielmy się opiniami, zamiast po prostu odrzucać głosy nowo przybyłych, którzy jeszcze nie dostali TAK!
rinogo

1
Zgadzam się, wygląda to na wykonalne
Felipe Valdes

3

Otrzymałem ten błąd po użyciu $ .getJSON () z JQuery. Właśnie zmieniłem post:

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
czy to jest odpowiedź czy pytanie?
Takarii

To dobre szybkie rozwiązanie. Zmiana z get na post pozwala na długi URL bez jakiejkolwiek zmiany konfiguracji serwera.
mt025

1

Fragment dokumentu RFC 2616: Hypertext Transfer Protocol - HTTP / 1.1 :

Metoda POST służy do żądania, aby serwer pochodzenia zaakceptował jednostkę zawartą w żądaniu jako nowego podwładnego zasobu określonego przez identyfikator żądania w wierszu żądania. POST został zaprojektowany, aby umożliwić jednolitą metodę obejmującą następujące funkcje:

  • Opis istniejących zasobów;
  • Wysyłanie wiadomości do tablicy ogłoszeń, grupy dyskusyjnej, listy mailingowej lub podobnej grupy artykułów;
  • Udostępnienie bloku danych, np. Wynikającego z przesłania formularza, do procesu obsługi danych ;
  • Rozszerzanie bazy danych poprzez operację dołączania.

8
Nie widząc, jak to odpowiada na pytanie…?
kwiecień

Oryginalny plakat informował, że zapisy są aktualizowane. W przypadku aktualizacji dobrą praktyką jest użycie POST lub PUT, a nie GET. Ale oczywiście może się zdarzyć, że maksymalny limit adresu URL zostanie przekroczony podczas pobierania rekordów do wyświetlenia przed aktualizacją, a następnie metoda GET jest odpowiednia, ale może się nie powieść z powodu tego limitu. Oryginalny plakat nie wspomniał, na jakim etapie pojawia się problem, więc można przypuszczać, że był on podczas samej aktualizacji, ale nie mamy pewności ...
JustAMartin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.