如何解决HTTP 414“请求URI太长”错误?


103

我已经开发了一个PHP网络应用程序。我给用户一个选项,可以一次更新多个问题。这样做时,有时用户会遇到此错误。有什么办法可以增加apache中URL的长度?


如果您在Windows服务器和/或IIS / ASP.NET应用程序中看到此错误,请参阅问题:stackoverflow.com/q/23237538/12484
Jon Schneider

Answers:


166

在Apache下,该限制为可配置值LimitRequestLine。如果要支持更长的请求URI,请将此值更改为大于其默认值8190的值。该值在/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和更新失败)。如果更新失败,您甚至可以使用每个字段的错误消息来描述失败。
Mike DeSimone 2012年

5
我想得很晚,所以我想分享一下。如果您无法LimitRequestLine在httpd.conf文件中的任何位置找到该单词,只需在您喜欢的任何位置添加该行即可。例如:LimitRequestLine 100000
Jules Colle

感谢您的回答和解释,您节省了我的时间。:)
五月saghira 2015年

16

根据约翰的回答,我将GET请求更改为POST请求。它可以工作,而无需更改服务器配置。所以我去寻找如何实现这一点。以下页面是有帮助的:

带有PHP的jQuery Ajax POST示例 (注意清理发布的数据注释)和

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

?>

我刚发送了12,000个字符,没有任何问题。


4

我有一个简单的解决方法。

假设您的URI的字符串stringdata太长。您可以根据服务器的限制将其分为多个部分。然后提交第一个文件,以我为例编写一个文件。然后提交下一个附加到先前添加的数据。


你能举个例子吗?我可以看到您是如何在用户生成字符串时对其进行分割的……
endyourif 2012年

4
非常便宜的解决方法。最好重新考虑域问题!
Muhammad Hewedy 2014年

13
这不应该有太多的否决票。当然,在某些情况下,提交多个请求是可以接受的解决方法。的确,答案的质量有点低,但这是SO的新用户所期望的。让我们表现出一些爱心并提供反馈,而不是仅仅对尚未“得到”的新来者投下反对票!
rinogo '16

1
我同意,它看起来可行
费利佩·瓦尔德斯

3

在从JQuery使用$ .getJSON()后,出现了此错误。我只是更改为发布:

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
这是答案还是问题?
Takarii '16

这是一个很好的快速解决方案。从获取更改为发布允许长URL,而无需任何服务器配置更改。
mt025

1

RFC 2616的摘录:超文本传输​​协议-HTTP / 1.1

POST方法用来请求原始服务器接受被附在请求由请求URI中使用Request-Line标识的资源的新下属的实体。POST旨在允许采用统一的方法来覆盖以下功能:

  • 注释现有资源;
  • 将消息发布到公告板,新闻组,邮件列表或类似的文章组;
  • 向数据处理过程提供数据块,例如提交表单的结果
  • 通过附加操作扩展数据库。

8
没有看到这如何回答问题..?
2014年

原始张贴者说,记录正在更新。对于更新,优良作法是使用POST或PUT而不是GET。但是,当然,可能是在更新之前检索要显示的记录时超出了URL最大限制,然后使用GET方法是合适的,但是由于这个限制,它可能会失败。原始海报没有提到问题出现在哪个阶段,因此可以假定是在更新本身中,但是我们不能确定...
JustAMartin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.