【问题标题】:How to display error on the same page when an error is returned by a form?表单返回错误时如何在同一页面上显示错误?
【发布时间】:2021-11-01 14:00:06
【问题描述】:

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

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

如果useridpassword 有误,我将退出程序而不写任何东西。这会导致 500 内部服务器错误。

我想使用 javascript 捕获这个 500 Internal server error。我曾尝试使用 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>

【问题讨论】:

  • 使用 Ajax。所以找到更多的例子

标签: javascript ajax cgi ibm-midrange


【解决方案1】:

是的,javascript 中的fetch api 可以将表单数据发布到您的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;
}

【讨论】:

    【解决方案2】:

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

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

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

    这不会是一个特别小的任务。您说您已经尝试过了,这可能会让您对它的范围有所了解(即远远超出 Stackoverflow 问题的范围)。

    几乎可以肯定,更明智的方法是追踪 500 错误的原因并更改 CGI 程序,以便它自己捕获它。

    【讨论】:

    • 谢谢。我使用 CGI 程序处理所有事情,并从程序中正确返回 HTML 页面。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多