วิธีส่งแบบฟอร์ม HTML โดยไม่ต้องเปลี่ยนเส้นทาง


100

ถ้าฉันมีรูปแบบเช่นนี้

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

ฉันจะส่งโดยไม่เปลี่ยนเส้นทางไปยังมุมมองอื่นโดย JavaScript / jQuery ได้อย่างไร

ฉันอ่านคำตอบมากมายจาก Stack Overflow แต่ทั้งหมดนี้เปลี่ยนเส้นทางฉันไปยังมุมมองที่ส่งคืนโดยฟังก์ชัน POST


คุณต้องการคำขอ XHR (AJAX)
Sterling Archer

2
XHR / AJAX เป็นวิธีหนึ่ง - ส่งโพสต์และได้รับการตอบกลับเบื้องหลังดังนั้นเบราว์เซอร์จะไม่ออกจากหน้าเว็บดังกล่าว อีกวิธีหนึ่งคือการเปลี่ยนเส้นทางฝั่งเซิร์ฟเวอร์หลังจากประมวลผลโพสต์ซึ่งขึ้นอยู่กับเทคโนโลยีเซิร์ฟเวอร์ที่คุณใช้
Stephen P

@StephenP ฉันใช้ ASP.NET MVC 5.1
Duke Nuke

@ ดุ๊กทั้งหมดที่ฉันพูดคือมีมากกว่าหนึ่งวิธี (ajax เทียบกับเซิร์ฟเวอร์เปลี่ยนเส้นทาง) และทางเลือกของคุณขึ้นอยู่กับความต้องการของคุณ เว็บไซต์สมัยใหม่มักจะต้องการทำ ajax ยังทราบว่าทุกคำตอบเหล่านี้จะพูดว่าคุณต้อง jQuery - jQuery ที่ดี แต่มีอยู่ในความเป็นจริงวิธีการอื่น ๆ ที่จะทำอาแจ็กซ์ ... แม้ว่าฉันแน่นอนจะใช้ jQuery ตัวเอง
Stephen P

1
ทางของฉันเรียบง่ายสะอาดตาและมีรหัสเพียง 2 บรรทัด ไม่ใช้สคริปต์และทำงานใน HTML4 ขึ้นไปแม้ว่า JavaScript จะปิดอยู่ก็ตาม
Issa Chanzi

คำตอบ:


75

เพื่อให้บรรลุสิ่งที่คุณต้องการคุณต้องใช้jQuery Ajaxดังต่อไปนี้:

$('#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
        }
    });
});

ลองอันนี้ด้วย:

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
       }
   });
}

ทางออกสุดท้าย

สิ่งนี้ทำงานได้อย่างไม่มีที่ติ ฉันเรียกฟังก์ชันนี้จากHtml.ActionLink(...)

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

วิธีนี้ใช้งานได้ดีปัญหาคือฉันไม่ต้องการให้ส่งโดยอัตโนมัติ (เสมอ) ด้วยวิธีนี้ ฉันต้องการมีฟังก์ชันที่มีชื่อเพื่อทำสิ่งนี้ที่คุณโพสต์ไว้ในคำตอบของคุณ ดังนั้นฉันสามารถเรียกมันด้วยตนเองเมื่อฉันต้องการเพื่อให้โพสต์แบบฟอร์ม เช่นเดียวกับด้านล่างฉันสามารถตั้งชื่อของฟังก์ชันที่จะเรียกใช้ @Html.ActionLink("Add a Report", "Create", "Reports", new { carId = Model.Id }, new { onclick = "FUNCTION_WHICH_SUBMITES_FORM()" })
Duke Nuke

สิ่งนี้ได้ผล:function SubForm (){ alert("1"); //e.preventDefault(); $.ajax({ url:'/Car/Edit/@Model.Id/', type:'post', data:$('#myForm').serialize(), success:function(){ alert("fasf"); } }); }
Duke Nuke

ด้วยเหตุผลบางประการวิธีแก้ปัญหาที่สองของคุณไม่ได้ผล แต่วิธีที่ฉันโพสต์ในความคิดเห็นล่าสุดทำ ฉันจะเพิ่มวิธีแก้ปัญหาในโพสต์ของคุณเพราะคุณเท่านั้นที่ฉันทำได้
Duke Nuke

1
อันที่สองต้องใช้งานได้เช่นกันอาจมีอย่างอื่น แต่ถ้าคุณพบวิธีแก้ปัญหาเราไม่จำเป็นต้องไปตามถนนนั้นในตอนนี้! ดีใจที่ได้ช่วย;)
Amin Jafari

ขอบคุณนี้คำตอบยังช่วยให้ฉันใส่ข้อความที่กำหนดเองในสถานที่ของรูปแบบหลังจากส่ง
Anupam

123

คุณสามารถบรรลุว่าด้วยการเปลี่ยนเส้นทางในรูปแบบของการที่มองไม่เห็นaction <iframe>ไม่ต้องใช้ JavaScript หรือสคริปต์ประเภทอื่น ๆ

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

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

1
นี่มันเยี่ยมมาก แต่ฉันจะทำอะไรได้บ้างหลังจากส่งแบบฟอร์มแล้ว? เช่นฟิลด์ข้อความของแบบฟอร์มจะต้องว่างโฟกัสกลับไปที่ฟิลด์แรกเป็นต้น?
Pranjal Choladhara

2
มีจาวาสคริปต์บางประเภทที่สามารถทำเช่นนั้นได้ เพียงแค่เปลี่ยน<input type='submit'...ไป<input type='reset'และเพิ่มonclick='document.forms["myForm"].submit();'>
อิสซา Chanzi

สวยตอบโจทย์! ใช้งานได้ดี
Cybrus

1
โปรดระวังมีแนวโน้มที่จะโหลดหน้าเว็บที่ฟอร์มของคุณอยู่ใน iframe ซ้ำซึ่งอาจทำให้เกิดปัญหาด้านประสิทธิภาพหากคุณกำลังสร้างแอปหรือเว็บไซต์ขนาดใหญ่
Alexandre Daubricourt

24

วางซ่อนไว้iFrameที่ด้านล่างของหน้าและtargetในแบบฟอร์มของคุณ:

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

ง่ายและรวดเร็ว โปรดทราบว่าแม้ว่าtargetแอตทริบิวต์จะยังคงได้รับการสนับสนุนอย่างกว้างขวาง (และรองรับใน HTML5) แต่ก็เลิกใช้งานใน HTML 4.01

ดังนั้นคุณควรใช้ Ajax เพื่อพิสูจน์อนาคต


ตาม MDN พฤติกรรมtargetนี้ถูกต้องสมบูรณ์ดังนั้น AJAX ยังคงเป็นทางเลือก
Daniel De León

22

เนื่องจากคำตอบปัจจุบันทั้งหมดใช้ jQuery หรือเทคนิคกับ iframe จึงคิดว่าไม่มีอันตรายใด ๆ ที่จะเพิ่มวิธีการด้วย JavaScript ธรรมดา:

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
ขอบคุณมาก!
Joshua Evans

ฉันให้หมวกคุณ ฉันใช้เวลาหลายชั่วโมงในการพยายามหาวิธีรับ jquery เพื่อส่งแบบฟอร์มไปยังแบ็กเอนด์ nginx ด้วยพารามิเตอร์ contentType = false และจะได้ผลลัพธ์เป็น 415 เสมอ นี่เป็นทางออกเดียวที่ฉันพบว่าแก้ปัญหาเฉพาะของฉันได้
user12066

8

โอเคฉันจะไม่บอกวิธีที่วิเศษในการทำเพราะมันไม่มี หากคุณมีแอตทริบิวต์การดำเนินการที่กำหนดไว้สำหรับองค์ประกอบแบบฟอร์มจะเปลี่ยนเส้นทาง

หากคุณไม่ต้องการให้เปลี่ยนเส้นทางก็อย่าตั้งค่าการดำเนินการและตั้งค่าใด ๆ onsubmit="someFunction();"

ในการที่someFunction()คุณทำสิ่งที่คุณต้องการ (ด้วย AJAX หรือไม่) และในตอนจบคุณเพิ่มreturn false;เพื่อบอกให้เบราว์เซอร์ไม่ต้องส่งแบบฟอร์ม ...


1
มีวิธีการทำที่มหัศจรรย์ ตั้งค่าแอตทริบิวต์เป้าหมายเพื่อให้แบบฟอร์มเปลี่ยนเส้นทางไปยังที่อื่นที่ไม่ใช่เฟรมปัจจุบัน หากคุณเพิ่ม iframe ที่มองไม่เห็นสำหรับสิ่งต่างๆเช่นนี้ในเพจของคุณ มันค่อนข้างง่าย
Issa Chanzi

5

คุณต้องการ Ajax เพื่อให้มันเกิดขึ้น สิ่งนี้:

$(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 จะถูกประดิษฐ์ขึ้น ฉันคิดว่าเราอยู่เหนือสิ่งนี้มานานแล้ว
Alfe

3

โซลูชันหนึ่งซับในปี 2020 หากข้อมูลของคุณไม่ได้ถูกส่งเป็นmultipart/form-dataหรือapplication/x-www-form-urlencoded:

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

3
หากคุณรวมสิ่งนี้เข้ากับ OP action="..."สิ่งนี้จะป้องกันการสลับหน้าได้อย่างมีประสิทธิภาพ แต่ยังป้องกันไม่ให้มีการส่งข้อมูลข้ามเครือข่าย
Kev

@Kev ฉันส่งข้อมูลของฉันผ่าน JS XHR เป็นการส่วนตัวนั่นคือเหตุผลที่ฉันไม่ต้องการเปลี่ยนเส้นทางหน้าเพราะเป็นแอป JS
Alexandre Daubricourt

@Kev ขอโทษฉันควรจะพูดถึงเรื่องนั้น
Alexandre Daubricourt

2

ดูpostฟังก์ชันของ jQuery

ฉันจะสร้างปุ่มและตั้งค่าonClickListener( $('#button').on('click', function(){});) และส่งข้อมูลในฟังก์ชัน

ดูpreventDefaultฟังก์ชั่นของ jQuery!


1

เอฟเฟกต์ที่ต้องการสามารถทำได้โดยการเลื่อนปุ่มส่งออกนอกแบบฟอร์มตามที่อธิบายไว้ที่นี่:

ป้องกันการโหลดหน้าซ้ำและเปลี่ยนเส้นทางในแบบฟอร์มส่ง ajax / jquery

แบบนี้:

<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

เมื่อใช้ข้อมูลโค้ดนี้คุณสามารถส่งแบบฟอร์มและหลีกเลี่ยงการเปลี่ยนเส้นทางได้ แต่คุณสามารถส่งผ่านฟังก์ชันความสำเร็จเป็นอาร์กิวเมนต์และทำสิ่งที่คุณต้องการ

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)
    });
}

จากนั้นทำ:

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

0

หากคุณสามารถควบคุมด้านหลังแล้วใช้สิ่งที่ต้องการแทนresponse.redirectresponse.send

คุณสามารถสร้างหน้า HTML ที่กำหนดเองสำหรับสิ่งนี้หรือเพียงแค่เปลี่ยนเส้นทางไปยังสิ่งที่คุณมีอยู่แล้ว

ใน 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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.