如何在不重定向的情况下提交 HTML 表单

问题描述 投票:0回答:14

如果我有这样的表格,

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

如何在不通过 JavaScript/jQuery 重定向到另一个视图的情况下提交它?

我从 Stack Overflow 中阅读了很多答案,但它们都将我重定向到 POST 函数返回的视图。

javascript jquery html forms
14个回答
194
投票

您可以通过将表单的

action
重定向到不可见的
<iframe>
来实现此目的。它不需要任何 JavaScript 或任何其他类型的脚本。

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

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

100
投票

为了实现你想要的,你需要使用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");
        }
    });
}

59
投票

由于当前所有答案都使用 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);
}

36
投票

在页面底部放置一个隐藏的

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 来面向未来。


14
投票

好吧,我不会告诉你一种神奇的方法,因为根本不存在。 如果您为表单元素设置了操作属性,它将重定向。

如果您不希望它重定向,只需不要设置任何操作并设置

onsubmit="someFunction();"

在你的

someFunction()
中你可以做任何你想做的事情(无论是否使用AJAX),最后,你添加
return false;
来告诉浏览器不要提交表单...


6
投票

自 2020 年起的单行解决方案,如果您的数据不打算作为

multipart/form-data
application/x-www-form-urlencoded
发送:

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

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

2
投票

参见 jQuery 的

post
函数。

我会创建一个按钮,并设置一个

onClickListener
(
$('#button').on('click', function(){});
),然后在函数中发送数据。

另外,请参阅 jQuery 的

preventDefault
函数!


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

即发即忘 vanilla js + svelte

function handleSubmit(e) {
    const request = new Request(`/products/${item.ItemCode}?_method=PUT`, { 
        method: 'POST', 
        body: new FormData(e.target),
    });
    fetch(request)
}

用于 Svelte:

<form method="post" on:submit|preventDefault={handleSubmit}>

0
投票

使用 Web 组件,您可以创建一个易于重用的表单组件,可以很好地处理这个问题。

function urlencodeFormData(fd: FormData) {
  let s = '';
  function encode(s: string) {
    return encodeURIComponent(s).replace(/%20/g, '+');
  }
  const formData: [string, string][] = [];
  fd.forEach((value, key) => {
    if (value instanceof File) {
      formData.push([key, value.name]);
    } else {
      formData.push([key, value]);
    }
  });
  for (const [key, value] of formData) {
    s += (s ? '&' : '') + encode(key) + '=' + encode(value);
  }
  return s;
}

const xhrOnSubmit = (event: SubmitEvent) => {
  console.log('Form submitted');
  const form: HTMLFormElement | null =
    event.target instanceof HTMLFormElement ? event.target : null;
  if (form == null) {
    console.error('Event target of form listener is not a form!');
    return;
  }
  let baseUrl = form.action;
  if (baseUrl == null || baseUrl === '') {
    baseUrl = window.location.href;
  }

  const requestUrl = new URL(baseUrl, window.location.href);
  
const shouldClear = form.getAttribute('data-clear-form') === 'true';

  // Decide on encoding
  const formenctype =
    event.submitter?.getAttribute('formenctype') ??
    event.submitter?.getAttribute('formencoding');
  const enctype =
    formenctype ??
    form.getAttribute('enctype') ??
    form.getAttribute('encoding') ??
    'application/x-www-form-urlencoded';

  // Decide on method
  let formMethod =
    event.submitter?.getAttribute('formmethod') ??
    form.getAttribute('method')?.toLowerCase() ??
    'get';

  const formData = new FormData(form);

  // Encode body
  let body: BodyInit | null = null;
  if (formMethod === 'get') {
    requestUrl.search = new URLSearchParams(
      urlencodeFormData(formData)
    ).toString();
  } else if (formMethod === 'post') {
    if (enctype === 'application/x-www-form-urlencoded') {
      body = urlencodeFormData(formData);
    } else if (enctype === 'multipart/form-data') {
      body = formData;
    } else if (enctype === 'text/plain') {
      let text = '';
      // @ts-ignore - FormData.entries() is not in the TS definition
      for (const element of formData.keys()) {
        text += `${element}=${JSON.stringify(formData.get(element))}\n`;
      }
    } else {
      throw new Error(`Illegal enctype: ${enctype}`);
    }
  } else if (formMethod === 'dialog') {
    // Allow default behavior
    return;
  } else {
    throw new Error(`Illegal form method: ${formMethod}`);
  }

  // Send request
  const requestOptions: RequestInit = {
    method: formMethod,
    headers: {
      'Content-Type': enctype,
    },
  };
  if (body != null && formMethod === 'post') {
    requestOptions.body = body;
  }
  const response = fetch(baseUrl, requestOptions).then((response) => {
    if (shouldClear) {
      form.reset();
    }
    if (response.ok) {
      form.dispatchEvent(
        new CustomEvent('xhr-form-success', {
          detail: response,
        })
      );
    } else {
      form.dispatchEvent(
        new CustomEvent('xhr-form-failure', {
          detail: response,
        })
      );
    }
    return response;
  });

  event.preventDefault();
};

customElements.define(
  'xhr-form',
  class extends HTMLFormElement {
    constructor() {
      console.log('Form constructed');
      super();
    }

    connectedCallback() {
      this.addEventListener('submit', xhrOnSubmit);
    }

    disconnectedCallback() {
      this.removeEventListener('submit', xhrOnSubmit);
    }
  },
  { extends: 'form' }
);

使用示例(与事件有关的所有内容都是可选的):

<form action="/printer" method="post" id="xhr-form" is="xhr-form">
  <h2>XHR POST Test</h2>
  <input type="text" name="name" placeholder="Name">
  <input type="number" name="age" placeholder="Age">
  <input type="submit" value="Submit">
</form>

<script>
  const xhrForm = document.getElementById('xhr-form');

  xhrForm.addEventListener('xhr-form-success', (event) => {
    console.log('XHR Form Success', event.detail);
  });

  xhrForm.addEventListener('xhr-form-failure', (event) => {
    console.log('XHR Form Failure', event.detail);
  });
</script>

0
投票

使用 HTTP 响应状态代码 204:

204 无内容

HTTP 204 No Content 成功状态响应代码表示请求已成功,但客户端不需要离开当前页面。

例如,在为 wiki 站点实现“保存并继续编辑”功能时可能会使用此功能。在这种情况下,将使用 PUT 请求来保存页面,并且将发送 204 No Content 响应以指示编辑器不应被其他页面替换。

204 响应默认是可缓存的(此类响应中包含 ETag 标头)。

但不幸的是,截至 2024 年中期 它无法在 iOS Safari 中工作


-2
投票

如果您控制后端,请使用类似

response.redirect
的内容而不是
response.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)
© www.soinside.com 2019 - 2024. All rights reserved.