Como resolvo um erro HTTP 414 “Solicitar URI muito longo”?

103

Desenvolvi um aplicativo da web em PHP. Estou dando uma opção para o usuário atualizar vários problemas de uma vez. Ao fazer isso, às vezes o usuário encontra esse erro. Existe alguma maneira de aumentar o comprimento da URL no apache?

JPro
fonte
Se você estiver vendo este erro em um servidor Windows e / ou em um aplicativo IIS / ASP.NET, consulte a pergunta: stackoverflow.com/q/23237538/12484
Jon Schneider

Respostas:

166

No Apache, o limite é um valor configurável LimitRequestLine,. Altere esse valor para algo maior do que seu padrão de 8190 se quiser oferecer suporte a um URI de solicitação mais longo. O valor está em /etc/apache2/apache2.conf . Caso contrário, adicione uma nova linha ( LimitRequestLine 10000) em AccessFileName .htaccess.

No entanto, observe que, se você está realmente chegando a esse limite, provavelmente está abusando GET. Você deve usar POSTpara transmitir esse tipo de dados - especialmente porque você até admite que está usando para atualizar valores. Se você verificar o link acima, notará que o Apache até diz "Em condições normais, o valor padrão não deve ser alterado."

John Feminella
fonte
Tentei usar o POST no início, mas esta é uma operação de atualização no banco de dados, e estou atualizando a página original usando os valores que foram postados originalmente nessa página.
JPro
8
JPro: Atualizar um banco de dados é mais ou menos o motivo exato pelo qual você usaria POST. Nada sobre o uso de POST impede que você preencha o mesmo formulário com os campos que acabaram de ser postados, então não tenho certeza do que você quer dizer com isso.
John Feminella
1
@JPro: A técnica usual nesse caso é POSTAR na mesma página. O manipulador da página (que pode ser o mesmo código para GET e POST) primeiro verifica os parâmetros POST, trata-os se os encontrar e, em seguida, retorna a página com os valores adequados preenchidos, que serão os valores atualizados ( se o POST e a atualização forem bem-sucedidos) ou os valores originais (se GET ou se o POST e a atualização falharem). Se a atualização falhar, você pode até ter mensagens de erro por campo descrevendo a falha.
Mike DeSimone
5
Descobri isso bem tarde, então gostaria de compartilhar. Se você não conseguir encontrar a palavra LimitRequestLineem nenhum lugar do arquivo httpd.conf, basta adicionar a linha em qualquer lugar que desejar. Por exemplo:LimitRequestLine 100000
Jules Colle
obrigado pela resposta e a explicação, você salvou meu dia. :)
maio saghira
16

Com base na resposta de John, alterei a solicitação GET para uma solicitação POST. Funciona, sem ter que alterar a configuração do servidor. Então, procurei como implementar isso. As seguintes páginas foram úteis:

Exemplo de jQuery Ajax POST com PHP (observe a observação de dados postados sanitize) e

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

Basicamente, a diferença é que a solicitação GET tem o url e os parâmetros em uma string e envia um valor nulo:

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

enquanto a solicitação POST envia o url e os parâmetros em comandos separados:

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

Aqui está um exemplo prático:

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

?>

Acabei de enviar mais de 12.000 caracteres sem problemas.

Atmelino
fonte
4

Eu tenho uma solução alternativa simples.

Suponha que seu URI tenha uma string stringdatamuito longa. Você pode simplesmente dividi-lo em várias partes, dependendo dos limites do seu servidor. Em seguida, envie o primeiro, no meu caso, para escrever um arquivo. Em seguida, envie os próximos para anexar aos dados adicionados anteriormente.

Shrey Gupta
fonte
você pode dar um exemplo? Posso ver como você divide a string quando ela é gerada pelo usuário ...
endyourif
4
Solução alternativa muito barata. É melhor reconsiderar o problema do domínio!
Muhammad Hewedy
13
Isso não merece tantos votos negativos. Certamente há situações em que enviar várias solicitações pode ser uma solução alternativa aceitável. É verdade que a qualidade da resposta é um pouco baixa, mas isso é esperado de um usuário que é novo em SO. Vamos mostrar um pouco de amor e oferecer feedback em vez de apenas rejeitar os recém-chegados que ainda não "entenderam" TÃO!
rinogo
1
Eu concordo, parece viável
Felipe Valdes,
3

Recebi este erro depois de usar $ .getJSON () do JQuery. Acabei de mudar para postar:

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
fonte
2
isso é uma resposta ou pergunta?
Takarii de
Esta é uma boa solução rápida. Mudar de get para post permite o URL longo sem qualquer alteração na configuração do servidor.
mt025
1

Um trecho do RFC 2616: Hypertext Transfer Protocol - HTTP / 1.1 :

O método POST é usado para solicitar que o servidor de origem aceite a entidade incluída na solicitação como um novo subordinado do recurso identificado pelo Request-URI na Request-Line. O POST é projetado para permitir um método uniforme para cobrir as seguintes funções:

  • Anotação de recursos existentes;
  • Publicar uma mensagem em um quadro de avisos, grupo de notícias, lista de e-mails ou grupo semelhante de artigos;
  • Fornecer um bloco de dados, como o resultado do envio de um formulário, a um processo de tratamento de dados ;
  • Estendendo um banco de dados por meio de uma operação de acréscimo.
Seu senso comum
fonte
8
Não vendo como isso responde à pergunta ..?
Afr
O autor da postagem original disse que os registros estão sendo atualizados. Para atualizações, é uma boa prática usar POST ou PUT e não GET. Mas, é claro, pode ser que o limite máximo da URL seja excedido ao recuperar os registros a serem exibidos antes da atualização, e então o método GET é apropriado, mas pode falhar devido a esse limite. O pôster original não mencionou em que estágio o problema surge, então pode-se supor que foi durante a atualização em si, mas não podemos ter certeza ...
JustAMartin