手机端浏览器上ES6中的Fetch回调执行 window.open没效果
今天发现了一个问题,PC端执行很好的代码,在手机端就没效果了,源码如下:
function projectPriceQRCode(pid, pnum) { let _width = 430; let url = 'ProjectPriceQRCode?width=' + _width + "&priceid=" + pid + "&pricenumber="+pnum; fetch(url, { method: 'GET', // or 'PUT' }).then(res => res.text()) .catch(error => { console.error('Error:', error); }) .then(response => { if (response!="") { window.open(response); } }); };
看着没毛病的代码,但是有异常的情况是:这段代码在PC端能正常工作,点击后能打开新的窗口,但在手机端点击没有反应。
可能原因及解决方案
1. 浏览器弹窗拦截
大部分手机浏览器默认会拦截通过异步回调(fetch 的 then)执行的 window.open,因为这不算是用户直接触发的操作,安全策略不同于PC端浏览器。
背景:
多数浏览器(尤其是移动端)只允许在直接的用户事件回调(比如onclick函数内)中调用 window.open,而在异步的 Promise 回调中调用容易被拦截。
2. 跨域或URL问题
如果 ProjectPriceQRCode?width=... 返回的URL有问题或者跨域,fetch 可能失败或返回空,导致 window.open没有被执行。
3. JavaScript错误
检查浏览器控制台是否有报错,尤其是在手机浏览器调试工具中。
问题定位示范(弹窗拦截为主要怀疑点)
将 window.open 移出异步回调,在点击事件处理函数中打开一个空白页,然后异步更改它的地址。例如:
function projectPriceQRCode(pid, pnum) { let _width = 430; let url = 'ProjectPriceQRCode?width=' + _width + "&priceid=" + pid + "&pricenumber=" + pnum; // 先立即打开一个新的窗口(保证是用户交互触发) let newWin = window.open('', '_blank'); fetch(url, { method: 'GET' }) .then(res => res.text()) .then(response => { if (response != "") { // 在拿到URL后再改变新窗口的地址 newWin.location = response; } else { newWin.close(); // 没有URL则关闭新窗口,避免空白页 } }) .catch(error => { console.error('Error:', error); newWin.close(); }); };
这样改动的思路是:
- 先在同步点击事件里打开空白页,绕开浏览器弹窗拦截
- 异步拿到真实URL后再跳转
浙公网安备 33010602011771号