Câu hỏi Yêu cầu đăng JavaScript như gửi biểu mẫu


Tôi đang cố gắng hướng trình duyệt đến một trang khác. Nếu tôi muốn có yêu cầu GET, tôi có thể nói

document.location.href = 'http://example.com/q=a';

Nhưng tài nguyên tôi đang cố gắng truy cập sẽ không phản hồi đúng cách trừ khi tôi sử dụng yêu cầu POST. Nếu điều này không được tạo động, tôi có thể sử dụng HTML

<form action="http://example.com/" method="POST">
  <input type="hidden" name="q" value="a">
</form>

Sau đó, tôi sẽ chỉ gửi biểu mẫu từ DOM.

Nhưng thực sự tôi muốn mã JavaScript cho phép tôi nói

post_to_url('http://example.com/', {'q':'a'});

Triển khai trình duyệt chéo tốt nhất là gì?

Chỉnh sửa 

Tôi xin lỗi tôi không rõ ràng. Tôi cần một giải pháp thay đổi vị trí của trình duyệt, giống như gửi biểu mẫu. Nếu điều này là có thể với XMLHttpRequest, nó không phải là hiển nhiên. Và điều này không nên không đồng bộ, cũng không sử dụng XML, vì vậy Ajax không phải là câu trả lời.


1279
2017-09-25 15:15


gốc


Như đã đề cập trong một chủ đề khác, có một plugin ".redirect" jquery hoạt động với phương thức POST hoặc GET. Nó tạo ra một hình thức với đầu vào ẩn và gửi nó cho bạn. Ví dụ: $ .redirect ('demo.php', {'arg1': 'value1', 'arg2': 'value2'}); github.com/mgalante/jquery.redirect/blob/master/… - OG Sean


Các câu trả lời:


function post(path, params, method) {
    method = method || "post"; // Set method to post by default if not specified.

    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
        }
    }

    document.body.appendChild(form);
    form.submit();
}

Thí dụ:

post('/contact/', {name: 'Johnny Bravo'});

CHỈNH SỬA: Kể từ khi điều này đã được upvoted rất nhiều, tôi đoán mọi người sẽ được sao chép-dán này rất nhiều. Vì vậy, tôi đã thêm hasOwnProperty kiểm tra để sửa bất kỳ lỗi vô ý nào.


1845
2017-09-25 15:28



Điều gì về mảng trong params dữ liệu? Jquery post () diễn giải ví dụ: "data: {array: [1, 2, 3]}" as? Array = 1 & array = 2 & array = 3. Mã whis cho kết quả khác. - Scit
Cảnh báo: Mặc dù có nhiều upvotes, giải pháp này bị giới hạn và không xử lý các mảng hoặc các đối tượng lồng nhau bên trong một biểu mẫu. Nếu không thì đó là một câu trả lời tuyệt vời. - emragins
@mricci Điểm của đoạn mã này là chuyển hướng trình duyệt đến một URL mới được chỉ định bởi hành động; nếu bạn đang ở trên cùng một trang, bạn chỉ có thể sử dụng AJAX truyền thống để POST dữ liệu của bạn. Vì trình duyệt nên điều hướng đến một trang mới, nội dung DOM của trang hiện tại sẽ không thành vấn đề - Ken Bellows
Lưu ý điều này có thể đã lỗi thời. Chúng ta có thể sử dụng FormData để đạt được điều này bằng cách sử dụng javascript thuần túy. - stevemao
@stevemao Sử dụng FormData vẫn cần gửi dữ liệu bằng cách sử dụng XMLHttpRequest, như đã nêu trong các chú thích ở trên, không thể hiển thị kết quả trong cửa sổ trình duyệt. - Hossein


Đây sẽ là phiên bản của câu trả lời được chọn bằng jQuery.

// Post to the provided URL with the specified parameters.
function post(path, parameters) {
    var form = $('<form></form>');

    form.attr("method", "post");
    form.attr("action", path);

    $.each(parameters, function(key, value) {
        var field = $('<input></input>');

        field.attr("type", "hidden");
        field.attr("name", key);
        field.attr("value", value);

        form.append(field);
    });

    // The form needs to be a part of the document in
    // order for us to be able to submit it.
    $(document.body).append(form);
    form.submit();
}

109
2018-04-04 00:21



Đã sửa lỗi: hiện đang thêm vào document.body - Ryan Delucchi
Hơi sửa đổi này để hỗ trợ mảng và đối tượng gist.github.com/hom3chuk/692bf12fe7dac2486212 - НЛО
Nếu giá trị chứa một ký tự xml dangeours, điều này sẽ không hoạt động trong ASP.NET encodeUriComponent (giá trị) là bắt buộc. Sau đó, UrlDecode cũng được yêu cầu ở phía máy chủ. - Stefan Steiger


Một cách thực hiện nhanh chóng và đơn giản về câu trả lời @Aaron:

document.body.innerHTML += '<form id="dynForm" action="http://example.com/" method="post"><input type="hidden" name="q" value="a"></form>';
document.getElementById("dynForm").submit();

Tất nhiên, bạn nên sử dụng một khung JavaScript như Prototype hoặc là jQuery...


62
2017-09-25 15:33



Có cách nào để làm điều này mà không có một trang web được tải trong cửa sổ trình duyệt hiện tại / tab? - pbreitenbach
có sử dụng thuộc tính target = '_ blank' trong phần tử biểu mẫu - Spidfire


Sử dụng createElement chức năng được cung cấp trong câu trả lời này, cần thiết do Sự hỏng hóc của IE với thuộc tính name trên các yếu tố được tạo bình thường với document.createElement:

function postToURL(url, values) {
    values = values || {};

    var form = createElement("form", {action: url,
                                      method: "POST",
                                      style: "display: none"});
    for (var property in values) {
        if (values.hasOwnProperty(property)) {
            var value = values[property];
            if (value instanceof Array) {
                for (var i = 0, l = value.length; i < l; i++) {
                    form.appendChild(createElement("input", {type: "hidden",
                                                             name: property,
                                                             value: value[i]}));
                }
            }
            else {
                form.appendChild(createElement("input", {type: "hidden",
                                                         name: property,
                                                         value: value}));
            }
        }
    }
    document.body.appendChild(form);
    form.submit();
    document.body.removeChild(form);
}

51
2017-09-25 15:29



Bạn có cần phải loại bỏ các con sau khi trình? Tuy vậy, trang này có biến mất không? - Nils
Không có việc sử dụng để xóa đứa trẻ sau khi đệ trình, ngoại trừ nếu một phiên được sử dụng và những dữ liệu đó được lưu lại. - Miloš
@CantucciHQ Trang có thể cũng không thay đổi ngay cả khi mục tiêu biểu mẫu không được đặt. Có 204 Không có nội dung, ví dụ. - Eugene Ryabtsev


Câu trả lời của Rakesh Pai thật tuyệt vời, nhưng có một vấn đề xảy ra với tôi (trong Safari) khi tôi cố gắng đăng một biểu mẫu với một trường được gọi là submit. Ví dụ, post_to_url("http://google.com/",{ submit: "submit" } );. Tôi đã vá các chức năng một chút để đi bộ xung quanh xung đột không gian biến này.

    function post_to_url(path, params, method) {
        method = method || "post";

        var form = document.createElement("form");

        //Move the submit function to another variable
        //so that it doesn't get overwritten.
        form._submit_function_ = form.submit;

        form.setAttribute("method", method);
        form.setAttribute("action", path);

        for(var key in params) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
        }

        document.body.appendChild(form);
        form._submit_function_(); //Call the renamed function.
    }
    post_to_url("http://google.com/", { submit: "submit" } ); //Works!

34
2017-07-15 20:50



2018 và vẫn không phải là câu trả lời tốt hơn? - iiirxs


Không, bạn không thể có yêu cầu đăng bài JavaScript như gửi biểu mẫu.

Những gì bạn có thể có là một biểu mẫu trong HTML, sau đó gửi nó bằng JavaScript. (như đã giải thích nhiều lần trên trang này)

Bạn có thể tự tạo HTML, bạn không cần JavaScript để viết HTML. Đó sẽ là ngớ ngẩn nếu mọi người đề nghị điều đó.

<form id="ninja" action="http://example.com/" method="POST">
  <input id="donaldduck" type="hidden" name="q" value="a">
</form>

Chức năng của bạn sẽ chỉ định cấu hình biểu mẫu theo cách bạn muốn.

function postToURL(a,b,c){
   document.getElementById("ninja").action     = a;
   document.getElementById("donaldduck").name  = b;
   document.getElementById("donaldduck").value = c;
   document.getElementById("ninja").submit();
}

Sau đó, sử dụng nó như thế nào.

postToURL("http://example.com/","q","a");

Nhưng tôi sẽ bỏ qua chức năng và chỉ cần làm.

   document.getElementById('donaldduck').value = "a";
   document.getElementById("ninja").submit();

Cuối cùng, quyết định phong cách sẽ xuất hiện trong tệp ccs.

.ninja{ 
  display:none;
}

Cá nhân tôi nghĩ rằng các hình thức nên được giải quyết theo tên nhưng đó không phải là quan trọng ngay bây giờ.


27
2017-08-19 01:00





Nếu bạn có Prototype cài đặt, bạn có thể thắt chặt mã để tạo và gửi biểu mẫu ẩn như sau:

 var form = new Element('form',
                        {method: 'post', action: 'http://example.com/'});
 form.insert(new Element('input',
                         {name: 'q', value: 'a', type: 'hidden'}));
 $(document.body).insert(form);
 form.submit();

24
2018-01-23 23:53





đây là câu trả lời của rakesh, nhưng với sự hỗ trợ cho mảng (đó là khá phổ biến trong các hình thức):

javascript đơn giản:

function post_to_url(path, params, method) {
    method = method || "post"; // Set method to post by default, if not specified.

    // The rest of this code assumes you are not using a library.
    // It can be made less wordy if you use one.
    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    var addField = function( key, value ){
        var hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", key);
        hiddenField.setAttribute("value", value );

        form.appendChild(hiddenField);
    }; 

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            if( params[key] instanceof Array ){
                for(var i = 0; i < params[key].length; i++){
                    addField( key, params[key][i] )
                }
            }
            else{
                addField( key, params[key] ); 
            }
        }
    }

    document.body.appendChild(form);
    form.submit();
}

oh, và đây là phiên bản jquery: (mã hơi khác một chút, nhưng lại hạ xuống cùng một thứ)

function post_to_url(path, params, method) {
    method = method || "post"; // Set method to post by default, if not specified.

    var form = $(document.createElement( "form" ))
        .attr( {"method": method, "action": path} );

    $.each( params, function(key,value){
        $.each( value instanceof Array? value : [value], function(i,val){
            $(document.createElement("input"))
                .attr({ "type": "hidden", "name": key, "value": val })
                .appendTo( form );
        }); 
    } ); 

    form.appendTo( document.body ).submit(); 
}

18
2018-03-22 01:41



p.s. bây giờ tôi thích sử dụng chức năng đó nhưng thay vì gửi biểu mẫu ở cuối, tôi chỉ cần trả lại nó cho người gọi. bằng cách này tôi có thể dễ dàng thiết lập các thuộc tính bổ sung hoặc làm các công cụ khác với nó nếu cần thiết. - kritzikratzi
Tuyệt quá! rất hữu dụng. Một thay đổi nhỏ cho những người dựa vào PHP ở phía máy chủ của biểu mẫu này, tôi đã thay đổi addField (khóa, params [key] [i]) thành addField (key + '[]', params [key] [i]). Điều này làm cho $ _POST [key] có sẵn dưới dạng mảng. - Thava
@Thava bạn cũng có thể đặt tên = "bla []" trên trường nhập của bạn. anyways, có những ngôn ngữ khác với php mà không hỗ trợ cú pháp [] vì vậy tôi để lại điều này không thay đổi. - kritzikratzi