Làm cách nào để giải quyết lỗi HTTP 414 “URI yêu cầu quá dài”?


103

Tôi đã phát triển một ứng dụng web PHP. Tôi đang đưa ra một tùy chọn cho người dùng để cập nhật nhiều vấn đề cùng một lúc. Khi làm như vậy, đôi khi người dùng gặp phải lỗi này. Có cách nào để tăng chiều dài của URL trong apache không?


Nếu bạn gặp phải lỗi này trên một máy chủ Windows và / hoặc trong một ứng dụng IIS / ASP.NET, xem câu hỏi: stackoverflow.com/q/23237538/12484
Jon Schneider

Câu trả lời:


166

Trong Apache, giới hạn là giá trị có thể định cấu hình LimitRequestLine,. Thay đổi giá trị này thành giá trị lớn hơn giá trị mặc định là 8190 nếu bạn muốn hỗ trợ URI yêu cầu dài hơn. Giá trị nằm trong /etc/apache2/apache2.conf . Nếu không, hãy thêm một dòng mới ( LimitRequestLine 10000) bên dưới AccessFileName .htaccess.

Tuy nhiên, lưu ý rằng nếu bạn thực sự sắp đạt đến giới hạn này, có thể bạn đang lạm dụng GETtừ đầu. Bạn nên sử dụng POSTđể truyền loại dữ liệu này - đặc biệt là vì bạn thậm chí thừa nhận rằng bạn đang sử dụng nó để cập nhật giá trị. Nếu bạn kiểm tra liên kết ở trên, bạn sẽ nhận thấy rằng Apache thậm chí còn nói "Trong điều kiện bình thường, giá trị không được thay đổi so với giá trị mặc định."


Lúc đầu, tôi đã thử sử dụng POST, nhưng đây là thao tác cập nhật trên cơ sở dữ liệu và tôi đang làm mới trang gốc bằng cách sử dụng các giá trị ban đầu được đăng lên trang đó.
JPro

8
JPro: Cập nhật cơ sở dữ liệu ít nhiều là lý do chính xác mà bạn sẽ sử dụng POST. Không có gì về việc sử dụng POST ngăn cản bạn điền cùng một biểu mẫu với các trường vừa được đăng, vì vậy tôi không chắc ý của bạn về điều đó.
John Feminella

1
@JPro: Kỹ thuật thông thường trong trường hợp đó là ĐĂNG lên cùng một trang. Trình xử lý cho trang (có thể là cùng một mã cho cả GET và POST) trước tiên sẽ kiểm tra các tham số POST, xử lý chúng nếu tìm thấy chúng, sau đó trả về trang với các giá trị thích hợp được điền vào, đó sẽ là các giá trị được cập nhật ( nếu POST và cập nhật thành công) hoặc các giá trị ban đầu (nếu GET hoặc nếu POST và cập nhật không thành công). Nếu cập nhật không thành công, bạn thậm chí có thể có thông báo lỗi theo từng trường mô tả lỗi.
Mike DeSimone

5
Tôi nhận ra điều này khá muộn, vì vậy tôi muốn chia sẻ nó. Nếu bạn không thể tìm thấy từ LimitRequestLineở bất kỳ đâu trong tệp httpd.conf của mình, chỉ cần tự thêm dòng vào bất kỳ đâu bạn muốn. Ví dụ:LimitRequestLine 100000
Jules Colle,

cảm ơn vì câu trả lời và giải thích, bạn đã cứu ngày của tôi. :)
may saghira

16

Dựa trên câu trả lời của John, tôi đã thay đổi yêu cầu GET thành yêu cầu ĐĂNG. Nó hoạt động mà không cần phải thay đổi cấu hình máy chủ. Vì vậy, tôi đã tìm cách thực hiện điều này. Các trang sau rất hữu ích:

jQuery Ajax POST ví dụ với PHP (Lưu ý nhận xét dữ liệu đã đăng sanitize) và

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

Về cơ bản, sự khác biệt là yêu cầu GET có url và tham số trong một chuỗi và sau đó gửi null:

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

trong khi yêu cầu POST gửi url và các tham số trong các lệnh riêng biệt:

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

Đây là một ví dụ hoạt động:

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

?>

Tôi vừa gửi hơn 12.000 ký tự mà không gặp vấn đề gì.


4

Tôi có một cách giải quyết đơn giản.

Giả sử URI của bạn có một chuỗi stringdataquá dài. Bạn có thể chỉ cần chia nó thành một số phần tùy thuộc vào giới hạn của máy chủ của bạn. Sau đó, gửi cái đầu tiên, trong trường hợp của tôi để viết một tệp. Sau đó, gửi những cái tiếp theo để thêm vào dữ liệu đã thêm trước đó.


bạn có thể cung cấp một ví dụ? Tôi có thể xem cách bạn chia chuỗi khi nó của người sử dụng tạo ra ...
endyourif

4
Cách giải quyết rất rẻ. Tốt hơn hết là bạn nên xem xét lại vấn đề tên miền!
Muhammad Hewedy

13
Điều này không xứng đáng có nhiều phiếu phản đối như vậy. Chắc chắn có những tình huống mà việc gửi nhiều yêu cầu có thể là một giải pháp chấp nhận được. Đúng, chất lượng của câu trả lời hơi thấp, nhưng điều đó được mong đợi từ một người dùng mới làm quen với SO. Hãy thể hiện một số tình yêu và cung cấp phản hồi thay vì chỉ tán thành những người mới đến chưa "nhận được" SO!
rinogo

1
Tôi đồng ý, có vẻ khả thi
Felipe Valdes

3

Tôi gặp lỗi này sau khi sử dụng $ .getJSON () từ JQuery. Tôi vừa đổi thành bài:

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
đây là câu trả lời hay câu hỏi?
Takarii

Đây là một sửa chữa nhanh tốt. Thay đổi từ nhận sang đăng cho phép URL dài mà không có bất kỳ thay đổi cấu hình máy chủ nào.
mt025,

1

Một đoạn trích từ RFC 2616: Giao thức truyền siêu văn bản - HTTP / 1.1 :

Các POST phương pháp được sử dụng để yêu cầu rằng các máy chủ gốc chấp nhận các thực thể khép kín trong yêu cầu như một cấp dưới mới của tài nguyên được xác định bởi Yêu cầu-URI trong Request-Line. POST được thiết kế để cho phép một phương pháp thống nhất bao gồm các chức năng sau:

  • Chú thích các nguồn hiện có;
  • Đăng tin nhắn lên bảng thông báo, nhóm tin, danh sách gửi thư hoặc nhóm bài báo tương tự;
  • Cung cấp một khối dữ liệu, chẳng hạn như kết quả của việc gửi biểu mẫu, cho quy trình xử lý dữ liệu ;
  • Mở rộng cơ sở dữ liệu thông qua hoạt động nối thêm.

8
Không thấy cách này trả lời câu hỏi ..?
Afr

Người đăng ban đầu nói rằng hồ sơ đang được cập nhật. Đối với các bản cập nhật, bạn nên sử dụng POST hoặc PUT chứ không phải GET. Tuy nhiên, tất nhiên, có thể giới hạn tối đa của URL bị vượt quá khi truy xuất các bản ghi để hiển thị trước khi cập nhật và sau đó phương thức GET là phù hợp, nhưng có thể không thành công vì giới hạn này. Những poster ban đầu đã không đề cập ở giai đoạn nào vấn đề phát sinh, vì vậy nó có thể giả định rằng đó là trong khi cập nhật chính nó, nhưng chúng ta không thể chắc chắn ...
JustAMartin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.