Wie löse ich einen HTTP 414-Fehler "URI zu lang anfordern"?

103

Ich habe eine PHP-Web-App entwickelt. Ich gebe dem Benutzer die Möglichkeit, mehrere Probleme auf einmal zu aktualisieren. Dabei stößt der Benutzer manchmal auf diesen Fehler. Gibt es eine Möglichkeit, die Länge der URL in Apache zu erhöhen?

JPro
quelle
Wenn Sie diesen Fehler auf einem Windows-Server und / oder in einer IIS / ASP.NET-App sehen, siehe Frage: stackoverflow.com/q/23237538/12484
Jon Schneider

Antworten:

166

Unter Apache ist das Limit ein konfigurierbarer Wert LimitRequestLine. Ändern Sie diesen Wert in einen Wert, der größer als der Standardwert von 8190 ist, wenn Sie einen längeren Anforderungs-URI unterstützen möchten. Der Wert befindet sich in /etc/apache2/apache2.conf . Wenn nicht, fügen Sie eine neue Zeile ( LimitRequestLine 10000) unter hinzu AccessFileName .htaccess.

Beachten Sie jedoch, dass Sie wahrscheinlich zunächst missbrauchen, wenn Sie tatsächlich auf dieses Limit stoßen GET. Sie sollten POSTdiese Art von Daten verwenden, zumal Sie sogar zugeben, dass Sie sie zum Aktualisieren von Werten verwenden. Wenn Sie den obigen Link überprüfen, werden Sie feststellen, dass Apache sogar sagt: "Unter normalen Bedingungen sollte der Wert nicht vom Standardwert geändert werden."

John Feminella
quelle
Ich habe zuerst versucht, POST zu verwenden, aber dies ist ein Aktualisierungsvorgang für die Datenbank, und ich aktualisiere die ursprüngliche Seite mit den Werten, die ursprünglich auf dieser Seite veröffentlicht wurden.
JPro
8
JPro: Das Aktualisieren einer Datenbank ist mehr oder weniger der genaue Grund, den Sie verwenden würden POST. Nichts an der Verwendung von POST hindert Sie daran, dasselbe Formular mit den gerade geposteten Feldern zu füllen. Ich bin mir also nicht sicher, was Sie damit meinen.
John Feminella
1
@JPro: Die übliche Technik in diesem Fall ist das POST auf derselben Seite. Der Handler für die Seite (der sowohl für GET als auch für POST derselbe Code sein kann) sucht zuerst nach POST-Parametern, verarbeitet sie, wenn er sie findet, und gibt dann die Seite mit den richtigen Werten zurück, die entweder die aktualisierten Werte sind ( wenn POST und die Aktualisierung erfolgreich sind) oder die ursprünglichen Werte (wenn GET oder wenn POST und die Aktualisierung fehlschlagen). Wenn das Update fehlschlägt, können sogar Fehlermeldungen pro Feld angezeigt werden, die den Fehler beschreiben.
Mike DeSimone
5
Ich habe das ziemlich spät herausgefunden, also würde ich es gerne teilen. Wenn Sie das Wort LimitRequestLinenirgendwo in Ihrer httpd.conf-Datei finden, fügen Sie die Zeile einfach selbst hinzu, wo immer Sie möchten. Zum Beispiel:LimitRequestLine 100000
Jules Colle
Danke für die Antwort und die Erklärung, du hast meinen Tag gerettet. :)
Mai saghira
16

Basierend auf Johns Antwort habe ich die GET-Anfrage in eine POST-Anfrage geändert. Es funktioniert, ohne dass die Serverkonfiguration geändert werden muss. Also habe ich mir überlegt, wie ich das umsetzen kann. Die folgenden Seiten waren hilfreich:

jQuery Ajax POST-Beispiel mit PHP (Beachten Sie die Anmerkung zur Bereinigung geposteter Daten) und

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

Grundsätzlich besteht der Unterschied darin, dass die GET-Anforderung die URL und die Parameter in einer Zeichenfolge enthält und dann null sendet:

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

Während die POST-Anforderung die URL und die Parameter in separaten Befehlen sendet:

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

Hier ist ein Arbeitsbeispiel:

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

?>

Ich habe gerade über 12.000 Zeichen ohne Probleme gesendet.

atmelino
quelle
4

Ich habe eine einfache Problemumgehung.

Angenommen, Ihre URI hat eine stringdatazu lange Zeichenfolge . Sie können es einfach in mehrere Teile aufteilen, abhängig von den Grenzen Ihres Servers. Dann reichen Sie die erste ein, in meinem Fall, um eine Datei zu schreiben. Senden Sie dann die nächsten, um sie an zuvor hinzugefügte Daten anzuhängen.

Shrey Gupta
quelle
Können Sie ein Beispiel geben? Ich kann sehen, wie Sie die Zeichenfolge teilen, wenn sie vom Benutzer generiert wird ...
endyourif
4
Sehr günstige Problemumgehung. Es ist besser, das Domain-Problem zu überdenken!
Muhammad Hewedy
13
Dies verdient nicht so viele Abstimmungen. Es gibt sicherlich Situationen, in denen das Senden mehrerer Anforderungen eine akzeptable Problemumgehung sein kann. Die Qualität der Antwort ist zwar etwas gering, aber das ist von einem Benutzer zu erwarten, der SO noch nicht kennt. Lassen Sie uns etwas Liebe zeigen und Feedback geben, anstatt nur Neulinge herunterzustimmen, die SO noch nicht "bekommen"!
Rinogo
1
Ich stimme zu, es sieht machbar aus
Felipe Valdes
3

Ich habe diesen Fehler erhalten, nachdem ich $ .getJSON () von JQuery verwendet habe. Ich habe gerade geändert, um zu posten:

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!");
    });
Fusca Software
quelle
2
Ist das eine Antwort oder eine Frage?
Takarii
Dies ist eine gute schnelle Lösung. Der Wechsel von get zu post ermöglicht die lange URL ohne Änderung der Serverkonfiguration.
mt025
1

Ein Auszug aus dem RFC 2616: Hypertext Transfer Protocol - HTTP / 1.1 :

Die POST- Methode wird verwendet, um anzufordern, dass der Ursprungsserver die in der Anforderung enthaltene Entität als neuen Untergebenen der Ressource akzeptiert, die durch den Anforderungs-URI in der Anforderungszeile identifiziert wird. POST wurde entwickelt, um eine einheitliche Methode zu ermöglichen, die die folgenden Funktionen abdeckt:

  • Anmerkung zu vorhandenen Ressourcen;
  • Senden einer Nachricht an ein Schwarzes Brett, eine Newsgroup, eine Mailingliste oder eine ähnliche Artikelgruppe;
  • Bereitstellen eines Datenblocks, z. B. des Ergebnisses des Absendens eines Formulars, für einen Datenverarbeitungsprozess ;
  • Erweitern einer Datenbank durch einen Anhängevorgang.
Ihr gesunder Menschenverstand
quelle
8
Nicht zu sehen, wie dies die Frage beantwortet ..?
Afr
Das Originalplakat sagte, dass die Aufzeichnungen aktualisiert werden. Für Updates empfiehlt es sich, POST oder PUT und nicht GET zu verwenden. Natürlich kann es sein, dass das maximale URL-Limit überschritten wird, wenn die anzuzeigenden Datensätze vor dem Aktualisieren abgerufen werden. Die GET-Methode ist dann geeignet, kann jedoch aufgrund dieses Limits fehlschlagen. Das Originalplakat hat nicht erwähnt, zu welchem ​​Zeitpunkt das Problem auftritt, daher kann davon ausgegangen werden, dass es während des Updates selbst
aufgetreten ist