小程序
小游戏
企业微信
微信支付
扫描小程序码分享
微信纯H5签约唤起签约页面后,重新返回到唤起页面,iphone13 或某些浏览器直接返回域名根目录下了。而不是当前唤起页面。
5 个回答
加粗
标红
插入代码
插入链接
插入图片
上传视频
Q:h5纯签约或公众号纯签约签约完成后点击完成按钮返回的是商户首页,不是发起签约请求的页面
A:
1.浏览器发起签约场景:
问题根因:referer由于客户端webview内核安全策略变更,需要源页面进行授权后,才能获取完整URL,否则无法在签约完成后,原路跳回商户的H5
解决方案:
商户跳转前的源H5页面,需要在html中做referrer-policy的授权声明:
方法一(推荐):
<meta name="referrer" content="no-referrer-when-downgrade">
方法二:
<meta name="referrer" content="unsafe-url">
安全策略详情可参考:https://developers.google.com/web/updates/2020/07/referrer-policy-new-chrome-default
Referrer-Policy声明的用法可参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referrer-Policy
注意:
① 商户需要检查一下html里面是否有多个meta name="Referrer"的声明(比如声明了一个<meta name="Referrer" content="origin" />,会覆盖开头的声明,需要删掉)
② 检查发起签约页面跳转微信时是否有处理过(比如中转页面或着在后台跳转的),必须是商户前端发起的跳转,否者不会生效
③由于iOS15对referrer policy更加严格,referer只带了host没有带path,但iOS14以及之前版本的referer带了host和path,导致了iOS15以上目前只能返回商户域名页面
2.商户发起签约页面地址中有片段标识符:
片段标识符(URI Fragment,即URL中#号后面的部分)仅用作浏览器端的处理,不会参与到服务端请求中,故签约完成回跳不会带上这部分信息。
你好,麻烦通过点击下方“反馈信息”按钮,提供出现问题的。
针对使用hash进行路由的项目,不管是Vue还是React,都不在适合作为唤起纯签约的主体界面,很多人用本地存储来标识状态,但如果遇到跨浏览器,这个标识就废了,referer跳转根本就不行了。
分享一下我们项目里的做法, 背景是:我们项目里是把整个支付抽离,作为一个支付中心,跟业务区分开来,支付/签约完成后都会跳转到业务需要的指定returnUrl进行结果渲染。(当然这个做法也有缺点,就是我们的签约链接在使用过一次后就会跳转到业务,用户如果没有签约,点了返回,那基本无法识别到,只能说在我们的业务架构上,这样的操作基本可以满足需求而已,这个案例就提供一个思路~~~)
具体步骤:
1、项目里新建一个contract.html,作为签约业务的中间页,专门用来进行纯签约跳转。
2、在原有业务逻辑中添加逻辑,判断如果是进行纯签约操作,则跳转到签约中间页进行操作。
// redirectUrl 是微信h5签约链接 // returnUrl 是需要执行前往的返回结果链接 // payTag 当前链接执行状态,操作过一次就回更新 window.location.href = `${url}/contract.html?redirectUrl=${encodeURIComponent(redirectUrl)}&returnUrl=${encodeURIComponent(returnUrl)}&payTag=1`;
3、当签约完成后,用户在微信点击“完成”按钮后,根据referer进入contract.html界面后,会执行跳转到returnUrl结果界面。
HTML示例如下,可作参考:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="referrer" content="no-referrer-when-downgrade"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>签约</title> <style> html, body { width: 100%; height: 100%; position: relative; } .loading { font-size: 16px; color: #999; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } </style> </head> <body> <p id="loading" class="loading">Loading...</p> <script> window.onload = function () { // 获取URI参数 const getURIParam = (paramName) => { const currentUrl = window.location.href; const regex = new RegExp("[?&]" + paramName + "(=([^&#]*)|&|#|$)"); const results = regex.exec(currentUrl); if (!results || !results[2]) { return ""; } else { const paramValue = decodeURIComponent(results[2].replace(/\+/g, " ")); return paramValue; } } // 更新url参数 function updateUrl(key, value) { var newurl = updateQueryStringParameter(key, value) window.history.replaceState({ path: newurl }, '', newurl); } // 更新url参数 function updateQueryStringParameter(key, value) { var uri = window.location.href; if (!value) { return uri; } var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i"); var separator = uri.indexOf('?') !== -1 ? "&" : "?"; if (uri.match(re)) { return uri.replace(re, '$1' + key + "=" + value + '$2'); } else { return uri + separator + key + "=" + value; } } const { href } = window.location; const redirectUrl = getURIParam("redirectUrl"); const returnUrl = getURIParam("returnUrl"); const hrefTag = getURIParam("payTag"); // payTag 1(可用) 0(已使用) if (redirectUrl && hrefTag && hrefTag === "1") { const copyUrl = decodeURIComponent(redirectUrl); updateUrl("payTag", "0"); // 更新链接状态 setTimeout(() => { document.getElementById("loading").innerText = "即将跳转签约..."; }, 700) setTimeout(() => { window.location.href = copyUrl; }, 1500) } else if (hrefTag && hrefTag === "0") { const copyUrl = decodeURIComponent(returnUrl); window.location.href = copyUrl; } else { alert("签约异常,请手动返回") } } </script> </body> </html>
请问最后解决了吗?
ios 15 没有办法吗?
关注后,可在微信内接收相应的重要提醒。
请使用微信扫描二维码关注 “微信开放社区” 公众号
Q:h5纯签约或公众号纯签约签约完成后点击完成按钮返回的是商户首页,不是发起签约请求的页面
A:
1.浏览器发起签约场景:
问题根因:referer由于客户端webview内核安全策略变更,需要源页面进行授权后,才能获取完整URL,否则无法在签约完成后,原路跳回商户的H5
解决方案:
商户跳转前的源H5页面,需要在html中做referrer-policy的授权声明:
方法一(推荐):
<meta name="referrer" content="no-referrer-when-downgrade">
方法二:
<meta name="referrer" content="unsafe-url">
安全策略详情可参考:https://developers.google.com/web/updates/2020/07/referrer-policy-new-chrome-default
Referrer-Policy声明的用法可参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referrer-Policy
注意:
① 商户需要检查一下html里面是否有多个meta name="Referrer"的声明(比如声明了一个<meta name="Referrer" content="origin" />,会覆盖开头的声明,需要删掉)
② 检查发起签约页面跳转微信时是否有处理过(比如中转页面或着在后台跳转的),必须是商户前端发起的跳转,否者不会生效
③由于iOS15对referrer policy更加严格,referer只带了host没有带path,但iOS14以及之前版本的referer带了host和path,导致了iOS15以上目前只能返回商户域名页面
2.商户发起签约页面地址中有片段标识符:
片段标识符(URI Fragment,即URL中#号后面的部分)仅用作浏览器端的处理,不会参与到服务端请求中,故签约完成回跳不会带上这部分信息。
针对使用hash进行路由的项目,不管是Vue还是React,都不在适合作为唤起纯签约的主体界面,很多人用本地存储来标识状态,但如果遇到跨浏览器,这个标识就废了,referer跳转根本就不行了。
分享一下我们项目里的做法, 背景是:我们项目里是把整个支付抽离,作为一个支付中心,跟业务区分开来,支付/签约完成后都会跳转到业务需要的指定returnUrl进行结果渲染。(当然这个做法也有缺点,就是我们的签约链接在使用过一次后就会跳转到业务,用户如果没有签约,点了返回,那基本无法识别到,只能说在我们的业务架构上,这样的操作基本可以满足需求而已,这个案例就提供一个思路~~~)
具体步骤:
1、项目里新建一个contract.html,作为签约业务的中间页,专门用来进行纯签约跳转。
2、在原有业务逻辑中添加逻辑,判断如果是进行纯签约操作,则跳转到签约中间页进行操作。
// redirectUrl 是微信h5签约链接 // returnUrl 是需要执行前往的返回结果链接 // payTag 当前链接执行状态,操作过一次就回更新 window.location.href = `${url}/contract.html?redirectUrl=${encodeURIComponent(redirectUrl)}&returnUrl=${encodeURIComponent(returnUrl)}&payTag=1`;
3、当签约完成后,用户在微信点击“完成”按钮后,根据referer进入contract.html界面后,会执行跳转到returnUrl结果界面。
HTML示例如下,可作参考:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="referrer" content="no-referrer-when-downgrade"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>签约</title> <style> html, body { width: 100%; height: 100%; position: relative; } .loading { font-size: 16px; color: #999; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } </style> </head> <body> <p id="loading" class="loading">Loading...</p> <script> window.onload = function () { // 获取URI参数 const getURIParam = (paramName) => { const currentUrl = window.location.href; const regex = new RegExp("[?&]" + paramName + "(=([^&#]*)|&|#|$)"); const results = regex.exec(currentUrl); if (!results || !results[2]) { return ""; } else { const paramValue = decodeURIComponent(results[2].replace(/\+/g, " ")); return paramValue; } } // 更新url参数 function updateUrl(key, value) { var newurl = updateQueryStringParameter(key, value) window.history.replaceState({ path: newurl }, '', newurl); } // 更新url参数 function updateQueryStringParameter(key, value) { var uri = window.location.href; if (!value) { return uri; } var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i"); var separator = uri.indexOf('?') !== -1 ? "&" : "?"; if (uri.match(re)) { return uri.replace(re, '$1' + key + "=" + value + '$2'); } else { return uri + separator + key + "=" + value; } } const { href } = window.location; const redirectUrl = getURIParam("redirectUrl"); const returnUrl = getURIParam("returnUrl"); const hrefTag = getURIParam("payTag"); // payTag 1(可用) 0(已使用) if (redirectUrl && hrefTag && hrefTag === "1") { const copyUrl = decodeURIComponent(redirectUrl); updateUrl("payTag", "0"); // 更新链接状态 setTimeout(() => { document.getElementById("loading").innerText = "即将跳转签约..."; }, 700) setTimeout(() => { window.location.href = copyUrl; }, 1500) } else if (hrefTag && hrefTag === "0") { const copyUrl = decodeURIComponent(returnUrl); window.location.href = copyUrl; } else { alert("签约异常,请手动返回") } } </script> </body> </html>
请问最后解决了吗?
ios 15 没有办法吗?