如何处理 form 表单提交后的响应信息?

目录

  • 1,问题
  • 2,思路
  • 3,实现
    • 1,核心逻辑
    • 2,具体实现
    • 3,其他问题

1,问题

需要在页面上显示支付宝付款码。后端对接后,前端请求后端获取数据,通过 form 表单提交数据最终会得到一个 url。但这个 url 不是图片链接而是一个 html,其中二维码以 canvas 的形式展示。

问题,如何在 dialog 弹窗中显示这个付款码?因为 form 表单请求后会刷新页面

2,思路

既然是一个 html,那可以使用 iframe 来显示这个图片,这样即便触发刷新也不影响当前页面。于是有2个思路:

  1. iframe 中发起 form 表单请求。
  2. form 表单的响应信息放到 iframe 中。

查阅资料,发现 form 表单有一个属性 target ,可以指定响应信息的显示位置。所以第2种更简单一点。

在 mdn 中,form.target 有 4 个可选值,但也可指定为 iframe.name。这样就能用 iframe 来显示 form 表单提交的响应信息。

3,实现

1,核心逻辑

需要一个 form 表单和 iframe

<form target="iframe">
  <input type="hidden" />
form>
<iframe name="iframe">iframe>

2,具体实现

<template>
  <div style="width: 200px; height: 200px">
    
    <iframe name="iframe" frameborder="0" class="alipay-iframe">iframe>
  div>
  <form target="iframe" ref="_formALIPAY" method="post" :action="info.submitUrl">
    <input v-for="(value, key) in info.formInputs" :key="key" :name="key" :value="value" type="hidden" />
  form>
template>
<script setup>
import { ref, watch, nextTick } from 'vue'

// { submitUrl: '', formInputs: {} }
const props = defineProps(['info'])
const _formALIPAY = ref(null)

watch(
  () => props.info,
  async (nv) => {
    if (nv) {
      await nextTick()
      _formALIPAY.value.submit()
    }
  }
)
script>
<style>
.alipay-iframe {
  width: 305px;
  height: 305px;
  transform-origin: 40px 40px; // 缩放原点
  transform: scale(0.52459); // (200 - 40)/305
}
style>

3,其他问题

网路问题导致请求慢时,iframe 是一个空白的区域,需要加一个 loading 动画。

1,通过 v-ifv-show 的方式来判断展示 loading

不行,因为无法得知 form 请求完成的时间

2,一开始展示 loading,当 iframe 有内容时,自动覆盖掉 loading

不行,因为 iframe 一开始就有宽高和背景,如果一开始置为空得到请求后再设置,那又回到了第一个方式。

3,背景图!(使用的方案)

iframe 加一个 gif 的背景图,这样图片展示后自动覆盖。

<style>
.alipay-iframe {
  // ...
  background-image: url('./loading.gif');
  background-repeat: no-repeat;
  background-size: 150px 150px;
  background-position: center;
}
style>

以上。

你可能感兴趣的:(问题解决,前端,javascript,form表单,vue.js)