Cách gửi biểu mẫu HTML mà không cần chuyển hướng


95

Nếu tôi có một biểu mẫu như thế này,

<form action="/Car/Edit/17" id="myForm" method="post" name="myForm"> ... </form>

làm cách nào để tôi có thể gửi nó mà không chuyển hướng đến một chế độ xem khác bằng JavaScript / jQuery?

Tôi đã đọc rất nhiều câu trả lời từ Stack Overflow, nhưng tất cả chúng đều chuyển hướng tôi đến dạng xem được trả về bởi hàm POST.


Bạn muốn có một yêu cầu XHR (AJAX)
Sterling Archer

2
XHR / AJAX là một cách - nó gửi bài đăng và nhận phản hồi đằng sau hậu trường, vì vậy trình duyệt không bao giờ rời khỏi trang mà nó đang ở trên. Một cách khác là chuyển hướng phía máy chủ sau khi xử lý bài đăng, điều này phụ thuộc vào công nghệ máy chủ bạn đang sử dụng.
Stephen P

@StephenP Tôi sử dụng ASP.NET MVC 5.1.
Duke Nuke

@Duke, tất cả những gì tôi đang nói là có nhiều hơn một cách tiếp cận (ajax so với chuyển hướng máy chủ) và lựa chọn của bạn tùy thuộc vào nhu cầu của bạn. Các trang web hiện đại rất có thể sẽ muốn làm ajax. Cũng lưu ý rằng tất cả những câu trả lời đang nói bạn cần jQuery - jQuery lớn nhưng có , trên thực tế, những cách khác để làm ajax ... mặc dù tôi thực sự sẽ sử dụng jQuery bản thân mình.
Stephen P

1
Cách của tôi rất đơn giản và thanh lịch, và nó chỉ có 2 dòng mã. Nó không sử dụng tập lệnh và hoạt động ở HTML4 trở lên, ngay cả khi JavaScript bị tắt.
Issa Chanzi

Câu trả lời:


74

Để đạt được những gì bạn muốn, bạn cần sử dụng jQuery Ajax như sau:

$('#myForm').submit(function(e){
    e.preventDefault();
    $.ajax({
        url: '/Car/Edit/17/',
        type: 'post',
        data:$('#myForm').serialize(),
        success:function(){
            // Whatever you want to do after the form is successfully submitted
        }
    });
});

Cũng thử cái này:

function SubForm(e){
    e.preventDefault();
    var url = $(this).closest('form').attr('action'),
    data = $(this).closest('form').serialize();
    $.ajax({
        url: url,
        type: 'post',
        data: data,
        success: function(){
           // Whatever you want to do after the form is successfully submitted
       }
   });
}

Giải pháp cuối cùng

Điều này đã hoạt động hoàn hảo. Tôi gọi chức năng này từHtml.ActionLink(...)

function SubForm (){
    $.ajax({
        url: '/Person/Edit/@Model.Id/',
        type: 'post',
        data: $('#myForm').serialize(),
        success: function(){
            alert("worked");
        }
    });
}

Điều này rất hiệu quả, vấn đề là tôi không muốn nó tự động (luôn) được gửi theo cách này. Tôi muốn có một chức năng có tên để làm công việc này mà bạn đã đăng trong câu trả lời của mình. Vì vậy, tôi có thể gọi nó theo cách thủ công khi tôi muốn, để làm cho nó đăng biểu mẫu. Giống như bên dưới, tôi có thể đưa ra tên của hàm để gọi. @Html.ActionLink("Add a Report", "Create", "Reports", new { carId = Model.Id }, new { onclick = "FUNCTION_WHICH_SUBMITES_FORM()" })
Duke Nuke

Điều này đã hoạt động:function SubForm (){ alert("1"); //e.preventDefault(); $.ajax({ url:'/Car/Edit/@Model.Id/', type:'post', data:$('#myForm').serialize(), success:function(){ alert("fasf"); } }); }
Duke Nuke

Vì một số lý do mà giải pháp thứ hai của bạn không hoạt động, nhưng giải pháp tôi đã đăng trong nhận xét cuối cùng đã làm được. Tôi sẽ thêm giải pháp của tôi vào bài viết của bạn, chỉ vì bạn mà tôi có thể đạt được điều này.
Duke Nuke

1
cái thứ hai cũng phải hoạt động, có thể có thứ gì đó khác với nó, nhưng nếu bạn tìm thấy giải pháp, chúng tôi không cần phải đi xuống con đường đó ngay bây giờ! rất vui vì nó đã giúp;)
Amin Jafari

Cảm ơn này câu trả lời cũng đã giúp tôi đặt một văn bản tùy chỉnh ở vị trí của các hình thức sau khi nộp
Anupam

116

Bạn có thể đạt được điều đó bằng cách chuyển hướng các hình thức của actionmột vô hình <iframe>. Nó không yêu cầu bất kỳ JavaScript hoặc bất kỳ loại tập lệnh nào khác.

<iframe name="dummyframe" id="dummyframe" style="display: none;"></iframe>

<form action="submitscript.php" target="dummyframe">
    <!-- Form body here -->
</form>

1
Điều đó thật tuyệt. Nhưng làm thế nào tôi có thể làm điều gì đó, sau khi biểu mẫu được gửi? tức là Các trường văn bản của biểu mẫu sẽ phải trống, tiêu điểm quay trở lại trường đầu tiên, v.v.?
Pranjal Choladhara

1
Có một số loại javascript có thể làm điều đó. Chỉ cần thay đổi <input type='submit'...để <input type='reset'và thêmonclick='document.forms["myForm"].submit();'>
Issa Chanzi

Câu trả lời tuyệt vời! Hoạt động tuyệt vời
Cybrus

Hãy cẩn thận, có khả năng tải lại trang mà biểu mẫu của bạn đang ở trong iframe, điều này có thể gây ra sự cố về hiệu suất nếu bạn đang xây dựng một ứng dụng hoặc một trang web lớn.
Alexandre Daubricourt

22

Đặt một ẩn iFrameở cuối trang của bạn và targetnó trong biểu mẫu của bạn:

<iframe name="hiddenFrame" width="0" height="0" border="0" style="display: none;"></iframe>

<form action="/Car/Edit/17" id="myForm" method="post" name="myForm" target="hiddenFrame"> ... </form>

Nhanh chóng và dễ dàng. Hãy ghi nhớ rằng trong khitarget thuộc tính này vẫn được hỗ trợ rộng rãi (và được hỗ trợ trong HTML5), nhưng nó đã không còn được chấp nhận trong HTML 4.01.

Vì vậy, bạn thực sự nên sử dụng Ajax để chứng minh trong tương lai.


Theo MDN, hành vi targetnày hoàn toàn hợp lệ, vì vậy AJAX vẫn là tùy chọn.
Daniel De León

18

Vì tất cả các câu trả lời hiện tại đều sử dụng jQuery hoặc thủ thuật với iframe, nên việc thêm phương thức chỉ với JavaScript đơn giản là điều không có hại:

function formSubmit(event) {
  var url = "/post/url/here";
  var request = new XMLHttpRequest();
  request.open('POST', url, true);
  request.onload = function() { // request successful
  // we can use server response to our request now
    console.log(request.responseText);
  };

  request.onerror = function() {
    // request failed
  };

  request.send(new FormData(event.target)); // create FormData from form that triggered event
  event.preventDefault();
}

// and you can attach form submit event like this for example
function attachFormSubmitEvent(formId){
  document.getElementById(formId).addEventListener("submit", formSubmit);
}

2
Cảm ơn bạn rất nhiều!
Joshua Evans

Tôi ngả mũ của tôi với bạn. Tôi đã dành hàng giờ để cố gắng tìm ra cách để jquery gửi một biểu mẫu đến một chương trình phụ trợ nginx với tham số contentType = false và kết quả là luôn nhận được kết quả là 415. Đây là giải pháp duy nhất tôi tìm thấy đã giải quyết được vấn đề cụ thể của tôi.
user12066

7

Được rồi, tôi sẽ không cho bạn biết một cách kỳ diệu để làm điều đó bởi vì không có. Nếu bạn có một thuộc tính action được đặt cho một phần tử biểu mẫu, nó sẽ chuyển hướng.

Nếu bạn không muốn nó chuyển hướng, chỉ cần không thiết lập bất kỳ hành động nào và đặt onsubmit="someFunction();"

Trong bạn, someFunction()bạn có thể làm bất cứ điều gì bạn muốn, (có AJAX hay không) và ở phần cuối, bạn thêm return false;yêu cầu trình duyệt không gửi biểu mẫu ...


1
Có một cách kỳ diệu để làm điều đó. Đặt một thuộc tính đích để biểu mẫu chuyển hướng đến một nơi nào đó khác với khung hiện tại. Nếu bạn thêm iframe ẩn cho những thứ như thế này trong các trang của bạn. Nó khá đơn giản.
Issa Chanzi

5

Bạn cần Ajax để biến nó thành hiện thực. Một cái gì đó như thế này:

$(document).ready(function(){
    $("#myform").on('submit', function(){
        var name = $("#name").val();
        var email = $("#email").val();
        var password = $("#password").val();
        var contact = $("#contact").val();

        var dataString = 'name1=' + name + '&email1=' + email + '&password1=' + password + '&contact1=' + contact;
        if(name=='' || email=='' || password=='' || contact=='')
        {
            alert("Please fill in all fields");
        }
        else
        {
            // Ajax code to submit form.
            $.ajax({
                type: "POST",
                url: "ajaxsubmit.php",
                data: dataString,
                cache: false,
                success: function(result){
                    alert(result);
                }
           });
        }
        return false;
    });
});

5
Có lý do cụ thể nào khiến bạn không thụt lề mã nguồn này không? Nó trông giống như mã từ những năm sáu mươi trước khi C được phát minh. Tôi nghĩ chúng ta đã vượt qua chuyện này trong một thời gian dài.
Alfe

2

Xem jQuery's post chức năng .

Tôi sẽ tạo một nút và đặt onClickListener($('#button').on('click', function(){}); ) và gửi dữ liệu trong hàm.

Ngoài ra, hãy xem preventDefaultchức năng của jQuery!


2

Giải pháp một lớp kể từ năm 2020, nếu dữ liệu của bạn không được gửi bằng multipart/form-datahoặc application/x-www-form-urlencoded:

<form onsubmit='return false'>
    <!-- ... -->           
</form>

3
Nếu bạn kết hợp điều này với OP action="...", điều này ngăn chặn hiệu quả việc chuyển đổi trang, nhưng cũng ngăn dữ liệu được gửi qua mạng.
Kev

@Kev Cá nhân tôi gửi dữ liệu của mình qua JS XHR, đó là lý do tại sao tôi không muốn chuyển hướng trang, vì đó là ứng dụng JS
Alexandre Daubricourt

@Kev Xin lỗi, lẽ ra tôi nên đề cập đến điều đó
Alexandre Daubricourt 28/03

1

Cũng có thể đạt được hiệu quả mong muốn bằng cách di chuyển nút gửi bên ngoài biểu mẫu như được mô tả ở đây:

Ngăn tải lại trang và chuyển hướng trên biểu mẫu gửi ajax / jquery

Như thế này:

<form id="getPatientsForm">
    Enter URL for patient server
    <br/><br/>
    <input name="forwardToUrl" type="hidden" value="/WEB-INF/jsp/patient/patientList.jsp" />
    <input name="patientRootUrl" size="100"></input>
    <br/><br/>
</form>

<button onclick="javascript:postGetPatientsForm();">Connect to Server</button>

1

Sử dụng đoạn mã này, bạn có thể gửi biểu mẫu và tránh chuyển hướng. Thay vào đó, bạn có thể chuyển hàm thành công dưới dạng đối số và làm bất cứ điều gì bạn muốn.

function submitForm(form, successFn){
    if (form.getAttribute("id") != '' || form.getAttribute("id") != null){
        var id = form.getAttribute("id");
    } else {
        console.log("Form id attribute was not set; the form cannot be serialized");
    }

    $.ajax({
        type: form.method,
        url: form.action,
        data: $(id).serializeArray(),
        dataType: "json",
        success: successFn,
        //error: errorFn(data)
    });
}

Và sau đó chỉ cần làm:

var formElement = document.getElementById("yourForm");
submitForm(formElement, function() {
    console.log("Form submitted");
});

0

Nếu bạn điều khiển back end, thì hãy sử dụng một cái gì đó như response.redirectthay vì response.send.

Bạn có thể tạo các trang HTML tùy chỉnh cho việc này hoặc chỉ chuyển hướng đến một cái gì đó bạn đã có.

Trong Express.js:

const handler = (req, res) => {
  const { body } = req
  handleResponse(body)
  .then(data => {
    console.log(data)
    res.redirect('https://yoursite.com/ok.html')
  })
  .catch(err => {
    console.log(err)
    res.redirect('https://yoursite.com/err.html')
  })
}
...
app.post('/endpoint', handler)
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.