当表单返回错误时,如何在同一页面上显示错误?



我已经用下面的代码建立了一个登录表单。

我使用的CGI版本CGIDEV2原生IBMi系列。我正在验证flower.cgi程序中的useridpassword。如果验证了useridpassword,我将加载另一个html文件以显示一个表。

如果useridpassword是错误的,我返回程序没有写任何东西。这将导致500内部服务器错误。

我想用javascript捕获这个500内部服务器错误。我曾尝试使用ajax,但没有成功,因为我对javascript的理解有限。

实现这一目标的最佳方法是什么?

<form method="POST" action="/nature/flower.cgi">
<!-- Username input -->
<div class="form-outline mb-4">
<input type="text" name="userid" id="form3Example3" class="form-control form-control-lg" style="text-transform:uppercase" placeholder="Enter a valid IBMi UserID" />
<label class="form-label" for="form3Example3">IBMi UserID</label>
</div>
<!-- Password input -->
<div class="form-outline mb-3">
<input type="password" name="passwd" id="form3Example4" class="form-control form-control-lg" placeholder="Enter password" />
<label class="form-label" for="form3Example4">Password</label>
<br>
</div>
<div class="d-flex justify-content-between align-items-center">
<!-- Checkbox -->
<div class="form-check mb-0">
<input class="form-check-input me-2" type="checkbox" value="" id="form2Example3" />
<label class="form-check-label" for="form2Example3">Remember me</label>
</div>
<a href="#!" class="text-body">Forgot password?</a>
</div>
<div class="text-center text-lg-start mt-4 pt-2">
<button type="submit" class="btn btn-primary btn-lg" style="padding-left: 2.5rem; padding-right: 2.5rem;">Login</button>
</div>
</form>

你无法从浏览器导航到的URL中捕获错误。

唯一的方法是用Ajax(发出请求的方式是)替换正常的表单提交。使用JavaScript处理的响应)。

一般来说,如果你要这样做,你还需要重写CGI程序,使其输出结构化数据(例如JSON)而不是语义数据(HTML)。

这不是一件特别小的事情。你说你已经尝试过了,这可能会让你对它的范围有一些了解(即远远超出Stackoverflow问题的范围)。

一个更明智的方法几乎肯定是跟踪500错误的原因,并更改CGI程序,使其能够捕获它自己。

是的,javascript中的fetchapi可以将表单数据发送到您的CGI程序并检查500响应代码。然后,网页可以显示错误消息,也可以运行form.submit()方法将表单实际提交到服务器。

下面是PHP和javascript代码来模拟整个过程。应该与CGI相似。关键是你把表单提交按钮的类型从"提交"改为"按钮"。这样,点击提交按钮就可以运行javascript代码,而不是将表单提交给服务器。

<?php
// site/tester/php/submit-form.php 
header("Content-type: text/html; charset:utf-8;");
?>
<?php
$userid = isset($_POST["userid"]) ? $_POST["userid"]: '' ; 
$passwd = isset($_POST["passwd"]) ? $_POST["passwd"]: '' ; 
$remember = isset($_POST["remember"]) ? $_POST["remember"]: 'off' ; 
if ( strtolower($userid) == 'alex')
{
http_response_code( 500 );
echo "$userid - invalid user name";
exit ;
}
?>
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" 
rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" 
crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="row mt-3">
<div class="col-auto">
<h1>submit form demo</h1>
</div>
</div>

</div>
<div class="container">
<div class="row mt-3">
<div class="col-4">
<form method="POST" id="main-form" action="./index.php">
<!-- Username input -->
<div class="form-outline mb-4">
<input type="text" name="userid" id="userid" 
class="form-control form-control-lg" 
value="<?= $userid ?>"
style="text-transform:uppercase" placeholder="Enter a valid IBMi UserID" />
<label class="form-label" for="userid">IBMi UserID</label>
</div>
<!-- Password input -->
<div class="form-outline mb-3">
<input type="password" name="passwd" id="passwd" class="form-control form-control-lg" 
placeholder="Enter password" />
<label class="form-label" for="passwd">Password</label>
<br>
</div>
<div class="d-flex justify-content-between align-items-center">
<!-- Checkbox -->
<div class="form-check mb-0">
<input class="form-check-input me-2" type="checkbox" 
<?= ($remember == 'on' ? 'checked' : '' ) ?>
name="remember" id="form2Example3" />
<label class="form-check-label" for="form2Example3">Remember me</label>
</div>
<a href="#!" class="text-body">Forgot password?</a>
</div>
<div class="text-center text-lg-start mt-4 pt-2">
<button id="login-button" type="button" class="btn btn-primary btn-lg" 
style="padding-left: 2.5rem; padding-right: 2.5rem;">
Login</button>
</div>
</form>    
</div>
</div>
<div id="login-errmsg-collapse" class="collapse row mt-3">
<div class="alert alert-warning" role="alert">
<p id="login-errmsg">Invalid login. User name does not exist.</p>
</div>
</div>
</div>
<div class="container">
<div class="row mt-3">
<div class="col-auto">
<p>userid: <?= $userid ?></p>
<p>passwd: <?= $passwd ?></p>
<p>remember: <?= $remember ?></p>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" 
crossorigin="anonymous"></script>
<script src="./app.js"></script>
</body>
// ./submit-form/app.js 
// enable the submit button click handler.
{
const elem = document.getElementById('login-button');
elem.addEventListener('click', event =>
{
login_click();
});
}
// -------------------------------- login_errmsg_show ---------------------
function login_errmsg_show( respText )
{
// show the response message in the bootstrap collapse alert box. 
{
const elem = document.getElementById('login-errmsg') ;
elem.textContent = respText ;
}
const myCollapse = document.getElementById('login-errmsg-collapse')
const bsCollapse = new bootstrap.Collapse(myCollapse, {
toggle: false
});
bsCollapse.show( ) ;
}
// -------------------------------- login_click -------------------
async function login_click()
{
const elem = document.getElementById('main-form');
if (elem)
{
const {respText, status} = await webpage_post( ) ;
if ( status != '500')
{
elem.submit();
}
else 
{
login_errmsg_show( respText ) ;
}
}
}
// --------------------------------- webpage_post -----------------------
async function webpage_post( )
{
const userid = document.getElementById('userid').value ;
const passwd = document.getElementById('passwd').value ;
const remember = 'on' ;

const url = "./index.php";
const params = { userid, passwd, remember } ;
const query = object_toQueryString(params);
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: query
});
const respText = await response.text();
const status = response.status ;
console.log( respText ) ;
return {respText, status} ;
}
// ------------------------- object_toQueryString ------------------------
function object_toQueryString(obj)
{
const qs = Object.keys(obj)
.map((key) => encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]))
.join('&');
return qs;
}

相关内容

最新更新