【汇总3种】vue项目中【H5】如何处理后端返回的支付宝form表单,如何实现支付跳转?

news2025/1/21 18:50:55

背景: 现在的项目,都需要付款,难免涉及支付宝或者微信支付。如果是支付宝支付,很多人都说,都已经2202年了,支付宝返回的还是form表单,然后,唤起支付宝的界面。
    一般来说,支付宝分为前端发起支付,和后台发起支付两种:
①前端发起支付,首先向后台发送订单数据,生成订单。然后,由前端调起手机的支付进行付款;
②如果采用的是,后台发起支付的方式,得到的返回是一个 < form >< /form >的表单html结构,自带< script >里面写的是监听提交按钮事件< /script >标签;
简单来说,由后台发起的支付会返回一个form表单,调用表单中的submit方法唤起支付宝界面。

一、实现思路

    首先,明确业务逻辑,支付跳转之前必然有一个提交订单信息【post】的过程,而我们的整个支付表单form是【post】之后返回发结果。返回的字符串结果如下所示:
在这里插入图片描述

在这里插入图片描述
整理一下,整个的支付流程(此流程,仅针对本公司业务,仅做参考):
①生成token,createToken;
②创建订单createOrder,生成orderCoder(ps:后面获取订单详情需要用到);
H5通过post接口调用,返回form表单(网上大多数案例,就是指的这一步);
④H5和步骤③同时发起,获取订单详情来轮询支付结果,最后,返回支付成功or支付失败的结果(ps:这个流程,后台调用前端无法拿到支付后的回调,目前,采取轮询调取后台支付状态的一个接口)。

二、相关代码

前端相关代码:
2.1 方法一:使用document.forms[0].submit(),提交表单操作
(1)首先,把表单的内容放在一个页面中:

<div class="aliform" v-html="aliform"></div>

(2)通过document.forms[0].submit(),获取当前页面的第一个表单提交:

<script>
export default {
	data() {
	    return {
	      aliform: "",
	    };
  	},
  	methods: {
		async iosAlipay(orderCode) {
      		let data = await requestAlipay(orderCode);
      		if (data.code == 20000) {
        		this.aliform = data.data;  //data.data就是支付宝返回给你的form,获取到的表单内容,具体样子可见上面的图片
        		this.$nextTick(() => {
        			// 获取订单详情来轮询支付结果
          			this.getOrderDetail();  
          			console.log(document.forms);  //跳转之前,可以先打印看看forms,确保后台数据和forms正确,否则,可能会出现一些奇奇怪怪的问题 ╮(╯▽╰)╭
          			document.forms[0].submit();  //重点--这个才是跳转页面的核心,获取第一个表单并提交
        		});
      		}
    	},
    	// 轮询结果
	    getOrderDetail() {
	    //轮询方法,因为支付是跳转到第三方支付宝,我们无法获知用户是否支付成功,或者用户支付成功后是否跳转回来。轮询方法,在一定时间内
	      clearTimeout(this.timer);
	      this.timer = setTimeout(() => {
	        let initTime = +new Date();
	        let loop = () => {
	          getOrderDetail({ orderCode: this.orderCode}).then((res) => {
	            if (res.code == 20000 && res.data && res.data.payStatus == 30) {
	              //支付成功的相关操作
	            } else {
	              let now = +new Date();
	              if (now - initTime < 45000) {
	                loop();
	              } else {
	                // 超时按照失败处理
	                //支付失败的结果
	              }
	            }
	          });
	        };
	        loop();
	      }, 500);
	    },
	}
}
</script>
<style lang="less" scoped >
.aliform {
  width: 1px;
  height: 1px;
  opacity: 0;
}
</style>

(3)题外话–了解一下js提供的document.forms方法:

(1)document.forms //表示获取当前页面的所有表单;
(2)document.forms[0] //表示获取当前页面的第一个表单;
(3)document.forms['exportServlet'] //表示获取当前页面的name="exportServlet"的表单
(4)submit() //表示提交函数

2.2 方法二:使用document.write(),就是重定向,覆盖原始页面

\\ 假设result是后端返回的from字符串
const newWindow = window.open('', '_self');  
newWindow.document.write(result);
newWindow.focus();

或者,直接使用document.write(xxx),来进行支付跳转

await postUserinfo('接口入参').then(res=>{
	document.write(res.data.result)
})

如果是在PC端处理,这种方式是没有问题的,但是需要注意三个问题:
①window.open()在接口回调中触发,可能会被游览器拦截;
②如果本身页面的地址是https的,如果返回的form的action是http的,游览器也会弹出安全提示;
③微信环境window.open()不生效。
2.3 方法三:动态创建div容器,将form渲染进去,js触发form提交
虽然,返回到result的form外面有html包裹,但是,可以动态的创建一个div容器,然后,将包含< html >的result渲染进去,通过js触发form表单的提交。

const div = document.createElement('formdiv');
div.innerHTML = result;
document.body.appendChild(div);
document.forms['cashierSubmit'].setAttribute('target', '_self');
document.forms['cashierSubmit'].submit();
div.remove();

对于H5来说,这种方案兼容性更好。需要注意的是:
一开始,将form的target设置成_blank,导致在ios上的游览器(微信环境,safari,UC)都无法实现form表单的提交。改成_self之后,问题解决。

或者,这样也可:

let divForm = document.getElementsByTagName('divform')
if (divForm.length) {
    document.body.removeChild(divForm[0])
}
const div = document.createElement('divform')
div.innerHTML = res.data // res.data就是支付宝返回给你的form
document.body.appendChild(div)
// document.forms[0].setAttribute('target', '_blank') // 加了_blank可能出问题所以我注释了
document.getElementById('alipay_submit').submit()

又或者,试下这样:

 //将接口返回的Form表单显示到页面
 document.querySelector('body').innerHTML = res.data; // res.data就是支付宝返回给你的form
 //调用submit 方法
 document.forms[0].submit()

参考博客:

UNI-APP解析支付宝返回FORM表单,唤起支付宝界面 https://www.freesion.com/article/6241970398/
Vue完美解决支付宝返回的form表单问题,这可能是最有效的解决办法了 https://blog.zixutech.cn/archives/324
vue项目中后端返回的支付宝form表单,怎么实现支付跳转? https://blog.csdn.net/qq_45934004/article/details/126156546
Vue自动提交form表单后,自动跳转第三方页面 https://www.jianshu.com/p/e2323b4e2cf9
开发笔记之uniapp 支付宝支付返回form表单解决方案 http://blog.haiya360.com/archives/766.html
vue 支付宝返回url 新窗口打开 https://blog.csdn.net/wax9092/article/details/86631151
H5处理支付宝接口返回form https://www.jianshu.com/p/8c5375671495
vue项目中后端返回的支付宝form表单,怎么实现支付跳转? https://blog.csdn.net/qq_45934004/article/details/126156546
Vue完美解决支付宝返回的form表单问题,这可能是最有效的解决办法了 https://blog.zixutech.cn/archives/324

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408501.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaScript 进阶教程】汽车商城根据价格区间筛选车辆案例

本案例源码链接&#xff08;非VIP可私聊获取&#xff09;&#xff1a;https://download.csdn.net/download/weixin_52212950/86286910https://download.csdn.net/download/weixin_52212950/86286910 文章导读&#xff1a; 这篇文章实现一个小案例&#xff1a;在购物平台选商品…

axios二次封装(详细+跨域问题)

一&#xff0c;为什么要对axios进行二次封装&#xff1f; 答&#xff1a;主要是要用到请求拦截器和响应拦截器; 请求拦截器&#xff1a;可以在发请求之前可以处理一些业务 响应拦截器&#xff1a;当服务器数据返回以后&#xff0c;可以处理一些事情 二&#xff0c;axios的二次…

html/javascript实现简单的上传

一、 上传用到的按钮类型是type file 二、 为了美化上传按钮&#xff0c;我们通常会自定义按钮&#xff0c;将默认的上传隐藏掉。 fileInputs.click() 触发上传按钮点击 三、 new FileReader() 读取文件内容方法&#xff1a; readAsText() 读取文本文件&#xff0c;(可以使用…

NodeJs - for循环的几种遍历方式

NodeJs - for循环的几种遍历方式一. for循环的几种遍历方式1.1 遍历的目标不一样1.2 空属性的遍历1.3 异步的调用二. 总结一. for循环的几种遍历方式 我们先来看下for循环的4种不同遍历方式&#xff1a; const arr [10,20,30,40,50];for (let i 0; i < arr.length; i) {…

VUE 年份范围选择器

VUE 年份范围选择器遇到一个需求,需要写一个年份选择器,是范围的年份选择器,比如:xxx年到xxx年 在使用elment UI的时候发现没有这种功能,于是采用el-date-picker 的年份选择器自己后封装了一个年份范围选择器 由于组件使用的地方很多,所以格式化都在组件中处理,回传格式在回传的…

Vue项目实战-vue2(移动端)

Vue项目实战(移动端)# 相关资料(一) 创建项目(二) 禁用Eslint(三) devtool(四) 添加less支持(五) vue路由配置(背诵)(六) 父子组件通信(背诵)(七) axios拦截器(背诵)(八) Sticky 粘性布局(九) 图片懒加载(十) 全局注册组件(十一) slot插槽(十二) 使用ui库需要关注的三点(十三)…

【Vue】Vue的安装

&#x1f3c6;今日学习目标&#xff1a;Vue3的安装 &#x1f603;创作者&#xff1a;颜颜yan_ ✨个人格言&#xff1a;生如芥子&#xff0c;心藏须弥 ⏰本期期数&#xff1a;第一期 &#x1f389;专栏系列&#xff1a;Vue3 文章目录前言Vue3安装独立版本CDN安装第一个Vue程序总…

vue递归组件—开发树形组件Tree--(构建树形菜单)

在 Vue 中&#xff0c;组件可以递归的调用本身&#xff0c;但是有一些条件&#xff1a; 该组件一定要有 name 属性要确保递归的调用有终止条件&#xff0c;防止内存溢出不知道大家有没遇到过这样的场景&#xff1a;渲染列表数据的时候&#xff0c;列表的子项还是列表。如果层级…

Vue基础--webpack介绍以及基础配置

写在最前&#xff1a;实际开发中需要自己配置webpack吗&#xff1f; 答案&#xff1a;不需要&#xff01; 实际开发中会使用命令行工具&#xff08;俗称CLI&#xff09;一键生成带有webpack的项目开箱即用&#xff0c;所有webpack的配置项都是现成的&#xff01;我们只需要知道…

python web开发基础

网站是存储在服务器上的文件&#xff0c;服务器是托管网站的计算机。这些服务器连接到一个称为 Internet 的网络。访问这些网站的计算机称为“客户端”。 要访问网站需要知道其IP地址&#xff0c;IP 地址是一串唯一的数字。每个设备都有一个 IP 地址。可以在控制台cmd输入命令…

前端笔记(10) Vue3 Router 监听路由参数变化

前言 Vue Router是开发Vue项目的必不可少的工具&#xff0c;也是极为重要的学习要点。 本篇介绍下Vue Router的基础使用和如何监听路由参数变化。 Vue Router入门 1 安装Router 安装Vue Router非常方便&#xff0c;只需执行一个命令&#xff0c;如果还不知道怎么搭建Vue项目…

详解 HttpServletResponse

详解 HttpServletResponse 核心方法代码示例1.设置响应状态码2.设置响应头3.设置响应内容&#xff08;1&#xff09;响应一个网页&#xff08;简单HTML&#xff09;&#xff08;2&#xff09;响应一个网页&#xff08;复杂HTML&#xff09;返回已有的一个网页1.重定向2.转发返回…

uniapp - 编译微信小程序项目的微信授权登录、获取微信手机号登录、最新版微信直接登录、手机与验证码登录的示例源码(适用于 uniapp 微信小程序项目,源代码直接开箱即用)超级详细的代码及注释

效果图 uniapp 项目编译微信小程序,一些常见的登录方式及源代码,示例代码干净整洁无BUG拿来即用。 本文示例实现了 uniapp 微信小程序项目的登录功能,包含微信授权登录、获取微信手机号登录、最新直接登录等, 你可以选择一个,直接复制源代码,稍微改改就能应用到你的项目…

后台管理系统

后台管理系统主要是我们内部人员使用的一款用来管理我们产品的一个系统&#xff0c;然后呢&#xff0c;我们今天写的呢是一个电商的后台管理系统。主要是可以用来管理我们的用户还有我们是商品的。 我们这个系统呢采用的是一个前后端分离的模式&#xff0c;主要是使用后端给我…

Vue 当页面进入全屏状态时element-ui的el-select下拉菜单不显示问题

在前两天进行页面全屏时&#xff0c;一切都还好好的&#xff0c;可当使用element-ui中的el-select时&#xff0c;下拉菜单却怎么也显示不出来&#xff0c;但只要退出全屏状态&#xff0c;立马就好。 非全屏时&#xff1a; 全屏时&#xff1a; 开始我以为是层级问题&#xff0…

前端加载高德离线地图的解决方案

核心是需要下载地图瓦片放在本地&#xff0c;脱离在线地图服务&#xff0c;实现离线加载地图。使用BIGMap工具下载地图离线瓦片到本地 下载地址&#xff1a;http://www.bigemap.com/reader/download/detail201802015.html BIGEMAP GIS Office-全能版需要注册试用版&#xff08;…

web前端面试宝典——带你直击面试重难点(40个经典题目,涵盖近90%的考点,码字2w,干货满满!)

系列文章目录 JavaScript 知识梳理&#xff0c;收录了web前端面试 95%以上 的高频考点&#xff0c;满满的干货。给你做一个高效的知识梳理&#xff0c;为你的面试保驾护航&#xff01; 内容参考链接HTML & CSS 篇HTML & CSS 篇JavaScript 篇&#xff08;一&#xff09;…

【微信小程序】条件渲染和列表渲染

&#x1f352;&#x1f352; 观众老爷们好啊&#xff0c;牛牛又更新了&#xff0c;上文我们详细了解了微信小程序中的事件绑定&#xff0c;那么今天我们就来讲讲WXML语法中的列表渲染和条件渲染&#xff0c;它俩也是非常重要的知识点&#xff0c;赶紧学起来吧。 &#x1f352;&…

如何更改ElementUI组件的图标大小以及标签属性

话不多说&#xff0c;直接上菜。 ElementUI提供的Rate评分组件的默认大小是这样的 图标太小了&#xff0c;想设置宽高、行高、尺寸&#xff0c;但代码不起作用。 打开浏览器调试&#xff0c;发现是用font-size设置才有用。 由此代码存在优先级问题&#xff0c;要提高优先级。…

vscode里面使用vue的一些插件,方便开发

1、vue 2 Snippets &#xff08;vue语法提示&#xff09; vue提示这个也可以 1.1 Vue VSCode Snippets 2、vetur Vetur支持.vue文件的语法高亮显示&#xff0c;除了支持template模板以外 3、Element UI Snippets(饿了么的提示) 4、indent-rainbow&#xff08;缩进高亮提示) 5…