Как устранить ошибку HTTP 414 «Слишком длинный URI запроса»?

103

Я разработал веб-приложение на PHP. Я даю пользователю возможность обновить несколько проблем за один раз. При этом иногда пользователь сталкивается с этой ошибкой. Есть ли способ увеличить длину URL-адреса в apache?

JPro
источник
Если вы видите эту ошибку на сервере Windows и / или в приложении IIS / ASP.NET, см. Вопрос: stackoverflow.com/q/23237538/12484
Джон Шнайдер,

Ответы:

166

В Apache предел - это настраиваемое значение LimitRequestLine. Измените это значение на большее, чем значение по умолчанию 8190, если вы хотите поддерживать более длинный URI запроса. Значение находится в /etc/apache2/apache2.conf . Если нет, добавьте новую строку ( LimitRequestLine 10000) под AccessFileName .htaccess.

Однако учтите, что если вы на самом деле столкнулись с этим пределом, вы, вероятно, GETс самого начала злоупотребляете . Вы должны использовать его POSTдля передачи такого рода данных - тем более, что вы даже признаете, что используете его для обновления значений. Если вы проверите ссылку выше, вы заметите, что Apache даже говорит: «В нормальных условиях значение не должно изменяться по сравнению со значением по умолчанию».

Джон Феминелла
источник
Сначала я попытался использовать POST, но это операция обновления базы данных, и я обновляю исходную страницу, используя значения, которые были изначально отправлены на эту страницу.
JPro
8
JPro: Обновление базы данных - это более или менее точная причина, по которой вы бы использовали POST. Ничто в использовании POST не мешает вам заполнять ту же форму только что опубликованными полями, поэтому я не уверен, что вы имеете в виду.
Джон Феминелла
1
@JPro: Обычный метод в этом случае - отправить POST на ту же страницу. Обработчик страницы (который может быть одним и тем же кодом для GET и POST) сначала проверяет параметры POST, обрабатывает их, если находит их, затем возвращает страницу с заполненными правильными значениями, которые будут либо обновленными значениями ( если POST и обновление прошло успешно) или исходные значения (если GET, или если POST и обновление не удалось). В случае сбоя обновления у вас могут быть даже сообщения об ошибках для каждого поля, описывающие сбой.
Майк Дезимоун
5
Я понял это довольно поздно, поэтому хотел бы поделиться этим. Если вы не можете найти слово LimitRequestLineв своем файле httpd.conf, просто добавьте строку самостоятельно в любом месте. Например:LimitRequestLine 100000
Жюль Колле
спасибо за ответ и объяснение, вы спасли мне день. :)
май сагира
16

Основываясь на ответе Джона, я изменил запрос GET на запрос POST. Он работает без изменения конфигурации сервера. Итак, я пошел искать, как это реализовать. Следующие страницы были полезны:

Пример jQuery Ajax POST с PHP (обратите внимание на примечание об очистке опубликованных данных) и

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

По сути, разница в том, что запрос GET имеет URL-адрес и параметры в одной строке, а затем отправляет null:

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

тогда как запрос POST отправляет URL-адрес и параметры в отдельных командах:

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

Вот рабочий пример:

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

?>

Я просто отправил без проблем более 12000 символов.

Атмелино
источник
4

У меня есть простой обходной путь.

Предположим, в вашем URI stringdataслишком длинная строка . Вы можете просто разбить его на несколько частей в зависимости от ограничений вашего сервера. Затем отправьте первый, в моем случае для записи файла. Затем отправьте следующие для добавления к ранее добавленным данным.

Шрей Гупта
источник
Вы можете привести пример? Я вижу, как вы разбиваете строку, когда ее генерирует пользователь ...
endyourif
4
Очень дешевое решение. Лучше пересмотреть проблему домена!
Мухаммад Хьюеди
13
Это не заслуживает такого количества голосов против. Безусловно, существуют ситуации, когда отправка нескольких запросов может быть приемлемым решением. Правда, качество ответа немного низкое, но этого следует ожидать от пользователя, который плохо знаком с SO. Давайте проявим немного любви и предложим обратную связь вместо того, чтобы просто отрицать новичков, которые еще не "поняли" ТАК!
rinogo
1
Я согласен, это выглядит жизнеспособным
Фелипе Вальдес
3

Я получил эту ошибку после использования $ .getJSON () из JQuery. Я просто изменил сообщение:

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
источник
2
это ответ или вопрос?
Takarii
Это хорошее быстрое решение. Переход от получения к публикации позволяет использовать длинный URL-адрес без изменения конфигурации сервера.
mt025
1

Выдержка из RFC 2616: Протокол передачи гипертекста - HTTP / 1.1 :

POST используется для запроса, чтобы исходный сервер принял объект, заключенный в запросе, как новый подчиненный ресурс, идентифицированный Request-URI в строке запроса. POST разработан, чтобы позволить единообразному методу охватывать следующие функции:

  • Аннотация существующих ресурсов;
  • Размещение сообщения на доске объявлений, в группе новостей, в списке рассылки или в аналогичной группе статей;
  • Предоставление блока данных, например результата отправки формы, процессу обработки данных ;
  • Расширение базы данных с помощью операции добавления.
Ваш здравый смысл
источник
8
Не видя, как это отвечает на вопрос ..?
Afr
На оригинальном плакате говорилось, что записи обновляются. Для обновлений рекомендуется использовать POST или PUT, а не GET. Но, конечно, может случиться так, что максимальный предел URL-адреса будет превышен при извлечении записей для отображения перед обновлением, и тогда подходящим будет метод GET, но он может выйти из строя из-за этого ограничения. В исходном плакате не упоминалось, на каком этапе возникает проблема, поэтому можно предположить, что это произошло во время самого обновления, но мы не можем быть уверены ...
JustAMartin