惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
量子位
G
Google Developers Blog
J
Java Code Geeks
N
Netflix TechBlog - Medium
博客园 - 聂微东
宝玉的分享
宝玉的分享
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
月光博客
月光博客
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
爱范儿
爱范儿
雷峰网
雷峰网
M
MIT News - Artificial intelligence
T
Tailwind CSS Blog
V
Visual Studio Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - 三生石上(FineUI控件)
Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
有赞技术团队
有赞技术团队
T
The Blog of Author Tim Ferriss

博客园 - 华安

C#中Microsoft.Extensions.Caching.Memory 与 System.Runtime.Caching.MemoryCache区别 自适应网格系统:CSS Grid中repeat()、auto-fill与auto-fit的深度解析 CSS3中响应式布局两大神器display:flex和display:grid springBoot中的 pom.xml文件 bulid学习 CSS中元素的display显示方式有多种,隐藏、块级、内联、内联-块级 SQl Server 中的 go 是什么作用 CSS中 display:flex的align-items: stretch; 移动端浏览器(尤其是 iOS Safari)的橡皮筋回弹效果(Overscroll / Bounce Effect) 用Flex实现兼容性好的全屏布局 在 VS Code 中使用 C# Dev Kit 和 Unity Tools 调试 Unity 2022 Unity 可编程物件(ScriptableObject) 微信小程序中的 联系客服 最基本的使用方法 wx.requestSubscribeMessage(Object object) 和 wx.requestSubscribeDeviceMessage(Object object) 这两个有什么区别 微信小程序中 wx.hideLoading() 后调用 wx.showToast()的问题 Windows 中启动 Nginx的常用命令 CSS进阶技巧:字体渐变、描边、倒影与渐变色描边全解析 netCore 中各DLL引用了 SkiaSharp.dll的问题 unity中预制体解包 在 Unity 中,Time.timeScale实现游戏暂停加速等 微信小程序中关联微信支付 unity中的 Navigation AI使用 C#中TaskCompletionSource(简称 TCS)学习 Unity 编辑器 中,快捷键 Ctrl + Shift + F 的功能 unity中按下 F键,让物体聚焦 微信中进入定页面的,判断时通过扫二维码进入的,还是点小程序名称进入的 MYSQL中从JSON字符串中提取指定的值 Unity2022中创建动画 Animation(旧方法) Unity 中区别,public 和 [SerializeField] Unity中 onCollisionEnter2D与OnTriggerEnter2D 区别 asp.netCore中给动态请求路径加客户端缓存
手机端浏览器上ES6中的Fetch回调执行 window.open没效果
华安 · 2026-09-08 · via 博客园 - 华安

今天发现了一个问题,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后再跳转