有没有办法使用防止默认并仍然收到 post 请求?
Is there a way to use prevent default and still receive post requests?
我正在尝试在我的后端正确验证表单数据,并且仍然能够在我的前端使用 Javascript 编写的表单验证获得良好的用户体验。我在前端完成了所有表单验证,为了获得我们想要的效果,我们在提交按钮上使用了 e.PreventDefault()
,这样我们就可以在不重新加载的情况下向用户显示任何输入错误。问题是,当您现在实际填写表格并单击提交时,由于 preventDefault,没有 POST 请求发送到服务器。
完全删除该行似乎解决了我们的服务器未收到 post 请求的问题,但这造成了前端表单验证完全没有意义的问题,因为错误消息没有显示,因为刷新页面。
Javascript 前端验证:
let btn = document.querySelector('.btn')
btn.addEventListener('click', function(e) {
e.preventDefault() // <---- THIS IS THE ISSUE
let firstName = document.querySelector('.firstName').value
let lastName = document.querySelector('.lastName').value
let email = document.querySelector('.email').value
let createPassword = document.querySelector('.createPassword').value
let verifyPassword = document.querySelector('.verifyPassword').value
let firstNameSubmit = false
let lasttNameSubmit = false
let emailSubmit = false
let createPasswordSubmit = false
let verifyPasswordSubmit = false
if (/^\s+$/.test(firstName) || firstName == null || firstName == '') {
document.querySelector('.firstNameError').innerHTML = 'First Name is a required field'
document.querySelector('.firstName').style.borderBottom = '1px solid red'
} else if (!/^\s+$/.test(firstName) || firstName !== null || firstName !== '') {
document.querySelector('.firstNameError').innerHTML = null
document.querySelector('.firstName').style.borderBottom = '1px solid #2ecc71'
firstNameSubmit = true
} if (/^\s+$/.test(lastName) || lastName == null || lastName == '') {
document.querySelector('.lastNameError').innerHTML = 'Last Name is a required field'
document.querySelector('.lastName').style.borderBottom = '1px solid red'
} else if (!/^\s+$/.test(lastName) || lastName !== null || lastName !== '') {
document.querySelector('.lastNameError').innerHTML = null
document.querySelector('.lastName').style.borderBottom = '1px solid #2ecc71'
lasttNameSubmit = true
} if (!/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
document.querySelector('.emailError').innerHTML = 'Please enter a valid email'
document.querySelector('.email').style.borderBottom = '1px solid red'
} else if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
document.querySelector('.emailError').innerHTML = null
document.querySelector('.email').style.borderBottom = '1px solid #2ecc71'
emailSubmit = true
} if (/^\s+$/.test(createPassword) || createPassword == null || createPassword == '' || createPassword.length < 6) {
document.querySelector('.createPasswordError').innerHTML = 'Password must be longer than 6 characters'
document.querySelector('.createPassword').style.borderBottom = '1px solid red'
} else if (!/^\s+$/.test(createPassword) || createPassword !== null || createPassword !== '' || createPassword.length >= 6) {
document.querySelector('.createPasswordError').innerHTML = null
document.querySelector('.createPassword').style.borderBottom = '1px solid #2ecc71'
createPasswordSubmit = true
} if (!createPasswordSubmit) {
document.querySelector('.verifyPasswordError').innerHTML = `Passwords don't match`
document.querySelector('.verifyPassword').style.borderBottom = '1px solid red'
} else if (verifyPassword == createPassword){
document.querySelector('.verifyPasswordError').innerHTML = null
document.querySelector('.verifyPassword').style.borderBottom = '1px solid #2ecc71'
verifyPasswordSubmit = true
}
去后端持有者:
http.HandleFunc("/signup", signupHandler) // inside func main()
func signupHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
tpl.ExecuteTemplate(w, "signup.html", nil)
fmt.Printf("METHOD: %s | URL: %v\n", r.Method, r.URL)
return
}
fmt.Printf("METHOD: %s | URL: %v\n", r.Method, r.URL)
r.ParseForm()
f := r.PostFormValue("fname")
l := r.PostFormValue("lname")
e := r.PostFormValue("email")
pw := r.PostFormValue("pass")
hash, err := helper.HashPassword(pw)
if err != nil {
fmt.Printf("Hashing Error")
}
fmt.Println("LoginValues")
fmt.Printf("%s\n, %s\n, %s\n, %s\n", f, l, e, hash)
}
注册模板HTML:
<form action="/signup" method="post">
<h3>First Name</h3>
<input name="fname" type="text" class="firstName">
<p class="firstNameError"></p>
<h3>Last Name</h3>
<input name="lname" type="text" class="lastName">
<p class="lastNameError"></p>
<h3>Email</h3>
<input name="email" type="text" class="email">
<p class="emailError"></p>
<h3>Create Password</h3>
<input name="pass" type="password" class="createPassword">
<p class="createPasswordError"></p>
<h3>Verify Password</h3>
<input type="password" class="verifyPassword">
<p class="verifyPasswordError"></p>
<button class="btn" type="submit">Register</button>
</form>
我只是想知道前端是否可以使用 preventDefault 进行后端表单验证,或者我是否需要以不同的方式处理这个概念,如果是这样的话如何?提前致谢!
因为它是一个 type="submit" 按钮,event.preventDefault() 阻止 "submit" 事件触发("submit" 事件将数据发送到后端)。
与其监听按钮上的 "click" 事件,我认为监听窗体上的 "submit" 事件更好。当您单击带有 type="submit."
的按钮时,它将在表单上触发
表单现在将成为活动的目标。
let form = document.getElementById('my-form')
form.addEventListener('submit', function(event) {})
因此,在函数的开头,您应该能够通过调用
来阻止提交操作
event.preventDefault();
但是,您也可以将表单存储到局部变量,因为这是触发提交事件的元素:
let form = event.target
然后,如果没有错误,您可以在函数结束时触发表单上的提交:
form.submit()
总计:
let form = document.getElementById('my-form')
form.addEventListener('submit', function(event) {
event.preventDefault()
let form = event.target
let errors = false;
//do all of the error checking here, if there's an error, set errors to true
if(!errors) {
form.submit()
}
})
(可能有更好的方法,但这就是我脑海中浮现的想法。此外,通过将 "name" 属性添加到每个输入,而不是查询每个字段)。
我通过摆弄@Maiya 提供的方法解决了这个问题。我退后一步,re-evaluated javascript 以及到底发生了什么。使用提交甚至监听器并在前端进行基本的表单验证,现在我可以在后端进行确保。在我将表单实例存储在变量中然后检查并提交之后,我最终使用了 e.preventDefault()
,或者它只是显示错误。
Javascript 变化:
let submit = document.getElementById("signupForm")
submit.addEventListener("submit", function(e){
let form = e.target // get form instance
e.preventDefault()
console.log(form)
// error handling
if (firstNameSubmit == false || lasttNameSubmit == false || emailSubmit == false || createPasswordSubmit == false || verifyPasswordSubmit == false) {
console.log('form not done')
} else { // form completed send to backend!
form.submit()
}
SignupHandler 更改:
user := &User{
fname: r.PostFormValue("fname"),
lname: r.PostFormValue("lname"),
email: r.PostFormValue("email"),
pw: r.PostFormValue("pass"),
}
user.hash = string(helper.HashPassword(user.pw))
//begin server validation
if user.fname == "" {
http.Redirect(w, r, "/signup", http.StatusBadRequest)
tpl.ExecuteTemplate(w, "signup.html", nil)
} else {
http.Redirect(w, r, "/login", http.StatusOK)
}
我正在尝试在我的后端正确验证表单数据,并且仍然能够在我的前端使用 Javascript 编写的表单验证获得良好的用户体验。我在前端完成了所有表单验证,为了获得我们想要的效果,我们在提交按钮上使用了 e.PreventDefault()
,这样我们就可以在不重新加载的情况下向用户显示任何输入错误。问题是,当您现在实际填写表格并单击提交时,由于 preventDefault,没有 POST 请求发送到服务器。
完全删除该行似乎解决了我们的服务器未收到 post 请求的问题,但这造成了前端表单验证完全没有意义的问题,因为错误消息没有显示,因为刷新页面。
Javascript 前端验证:
let btn = document.querySelector('.btn')
btn.addEventListener('click', function(e) {
e.preventDefault() // <---- THIS IS THE ISSUE
let firstName = document.querySelector('.firstName').value
let lastName = document.querySelector('.lastName').value
let email = document.querySelector('.email').value
let createPassword = document.querySelector('.createPassword').value
let verifyPassword = document.querySelector('.verifyPassword').value
let firstNameSubmit = false
let lasttNameSubmit = false
let emailSubmit = false
let createPasswordSubmit = false
let verifyPasswordSubmit = false
if (/^\s+$/.test(firstName) || firstName == null || firstName == '') {
document.querySelector('.firstNameError').innerHTML = 'First Name is a required field'
document.querySelector('.firstName').style.borderBottom = '1px solid red'
} else if (!/^\s+$/.test(firstName) || firstName !== null || firstName !== '') {
document.querySelector('.firstNameError').innerHTML = null
document.querySelector('.firstName').style.borderBottom = '1px solid #2ecc71'
firstNameSubmit = true
} if (/^\s+$/.test(lastName) || lastName == null || lastName == '') {
document.querySelector('.lastNameError').innerHTML = 'Last Name is a required field'
document.querySelector('.lastName').style.borderBottom = '1px solid red'
} else if (!/^\s+$/.test(lastName) || lastName !== null || lastName !== '') {
document.querySelector('.lastNameError').innerHTML = null
document.querySelector('.lastName').style.borderBottom = '1px solid #2ecc71'
lasttNameSubmit = true
} if (!/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
document.querySelector('.emailError').innerHTML = 'Please enter a valid email'
document.querySelector('.email').style.borderBottom = '1px solid red'
} else if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
document.querySelector('.emailError').innerHTML = null
document.querySelector('.email').style.borderBottom = '1px solid #2ecc71'
emailSubmit = true
} if (/^\s+$/.test(createPassword) || createPassword == null || createPassword == '' || createPassword.length < 6) {
document.querySelector('.createPasswordError').innerHTML = 'Password must be longer than 6 characters'
document.querySelector('.createPassword').style.borderBottom = '1px solid red'
} else if (!/^\s+$/.test(createPassword) || createPassword !== null || createPassword !== '' || createPassword.length >= 6) {
document.querySelector('.createPasswordError').innerHTML = null
document.querySelector('.createPassword').style.borderBottom = '1px solid #2ecc71'
createPasswordSubmit = true
} if (!createPasswordSubmit) {
document.querySelector('.verifyPasswordError').innerHTML = `Passwords don't match`
document.querySelector('.verifyPassword').style.borderBottom = '1px solid red'
} else if (verifyPassword == createPassword){
document.querySelector('.verifyPasswordError').innerHTML = null
document.querySelector('.verifyPassword').style.borderBottom = '1px solid #2ecc71'
verifyPasswordSubmit = true
}
去后端持有者:
http.HandleFunc("/signup", signupHandler) // inside func main()
func signupHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
tpl.ExecuteTemplate(w, "signup.html", nil)
fmt.Printf("METHOD: %s | URL: %v\n", r.Method, r.URL)
return
}
fmt.Printf("METHOD: %s | URL: %v\n", r.Method, r.URL)
r.ParseForm()
f := r.PostFormValue("fname")
l := r.PostFormValue("lname")
e := r.PostFormValue("email")
pw := r.PostFormValue("pass")
hash, err := helper.HashPassword(pw)
if err != nil {
fmt.Printf("Hashing Error")
}
fmt.Println("LoginValues")
fmt.Printf("%s\n, %s\n, %s\n, %s\n", f, l, e, hash)
}
注册模板HTML:
<form action="/signup" method="post">
<h3>First Name</h3>
<input name="fname" type="text" class="firstName">
<p class="firstNameError"></p>
<h3>Last Name</h3>
<input name="lname" type="text" class="lastName">
<p class="lastNameError"></p>
<h3>Email</h3>
<input name="email" type="text" class="email">
<p class="emailError"></p>
<h3>Create Password</h3>
<input name="pass" type="password" class="createPassword">
<p class="createPasswordError"></p>
<h3>Verify Password</h3>
<input type="password" class="verifyPassword">
<p class="verifyPasswordError"></p>
<button class="btn" type="submit">Register</button>
</form>
我只是想知道前端是否可以使用 preventDefault 进行后端表单验证,或者我是否需要以不同的方式处理这个概念,如果是这样的话如何?提前致谢!
因为它是一个 type="submit" 按钮,event.preventDefault() 阻止 "submit" 事件触发("submit" 事件将数据发送到后端)。
与其监听按钮上的 "click" 事件,我认为监听窗体上的 "submit" 事件更好。当您单击带有 type="submit."
的按钮时,它将在表单上触发表单现在将成为活动的目标。
let form = document.getElementById('my-form')
form.addEventListener('submit', function(event) {})
因此,在函数的开头,您应该能够通过调用
来阻止提交操作event.preventDefault();
但是,您也可以将表单存储到局部变量,因为这是触发提交事件的元素:
let form = event.target
然后,如果没有错误,您可以在函数结束时触发表单上的提交:
form.submit()
总计:
let form = document.getElementById('my-form')
form.addEventListener('submit', function(event) {
event.preventDefault()
let form = event.target
let errors = false;
//do all of the error checking here, if there's an error, set errors to true
if(!errors) {
form.submit()
}
})
(可能有更好的方法,但这就是我脑海中浮现的想法。此外,通过将 "name" 属性添加到每个输入,而不是查询每个字段)。
我通过摆弄@Maiya 提供的方法解决了这个问题。我退后一步,re-evaluated javascript 以及到底发生了什么。使用提交甚至监听器并在前端进行基本的表单验证,现在我可以在后端进行确保。在我将表单实例存储在变量中然后检查并提交之后,我最终使用了 e.preventDefault()
,或者它只是显示错误。
Javascript 变化:
let submit = document.getElementById("signupForm")
submit.addEventListener("submit", function(e){
let form = e.target // get form instance
e.preventDefault()
console.log(form)
// error handling
if (firstNameSubmit == false || lasttNameSubmit == false || emailSubmit == false || createPasswordSubmit == false || verifyPasswordSubmit == false) {
console.log('form not done')
} else { // form completed send to backend!
form.submit()
}
SignupHandler 更改:
user := &User{
fname: r.PostFormValue("fname"),
lname: r.PostFormValue("lname"),
email: r.PostFormValue("email"),
pw: r.PostFormValue("pass"),
}
user.hash = string(helper.HashPassword(user.pw))
//begin server validation
if user.fname == "" {
http.Redirect(w, r, "/signup", http.StatusBadRequest)
tpl.ExecuteTemplate(w, "signup.html", nil)
} else {
http.Redirect(w, r, "/login", http.StatusOK)
}