Navigator.share 仅在 iOS 中工作一次,第二次单击会引发错误“用户代理不允许请求...”

Posted

技术标签:

【中文标题】Navigator.share 仅在 iOS 中工作一次,第二次单击会引发错误“用户代理不允许请求...”【英文标题】:Navigator.share only working once in iOS, second click throws error "request is not allowed by the user agent..." 【发布时间】:2020-09-24 23:44:12 【问题描述】:

还有其他人遇到过这个问题吗?我正在实现 Web 共享 API 以向页面上的多个列表添加共享按钮。该代码最初似乎运行良好,因为我可以单击任何“共享”按钮,对话框将正确显示。

但是,如果我关闭对话框并尝试再次单击它,我会收到一条错误消息:“在当前上下文中,用户代理或平台不允许该请求,可能是因为用户拒绝了权限。”

更奇怪的是,我在所有这些关于如何实现 Web 共享 API 的教程网站上都遇到了同样的行为(例如:https://alligator.io/js/web-share-api/ - 尝试在页面中间多次单击“共享我!”按钮ios Safari。)

这是我的参考代码:

const shareButtons = document.querySelectorAll('.share');

for (const button of shareButtons) 
    button.addEventListener("click", async () => 
        if (navigator.share) 
            try 
                await navigator.share( 
                    url: button.getAttribute('data-url')
                );
             catch (err) 
                  alert(err.message);
            
         else 
            // fallback
        
    );

感谢我对此的任何见解 - 非常感谢

【问题讨论】:

【参考方案1】:

你用的是哪个版本的IOS?

IOS 14.0.1 中似乎存在一个已知错误,初始承诺无法解决。

https://developer.apple.com/forums/thread/662629

文章中建议的修复方法(对我有用)是:

navigator.share(...)
.then(() => 
    // this will never happen in IOS 14.0.1
)
.catch(error => 
    //this will catch the second share attempt
    window.location.reload(true); // now share works again
);

或者在你的情况下使用 try/catch

const shareButtons = document.querySelectorAll('.share');

for (const button of shareButtons) 
    button.addEventListener("click", async () => 
        if (navigator.share) 
            try 
                await navigator.share( 
                    url: button.getAttribute('data-url')
                );
             catch (err) 
                  // this will catch the second share attempt on ios14
                  window.location.reload(true); // now share works again
                  alert(err.message);
            
         else 
            // fallback
        
    );

缺点是它实际上意味着如果用户使用 IOS14,则必须单击两次才能触发第二次共享 - 但其他用户不会发生这种情况

【讨论】:

IOS 14.1 中仍有BUG 在共享 URL 时使用 Promise 可以为我解决此问题,但在共享文件时无法解决。【参考方案2】:

感谢所有关于这个非常有用的答案。我玩过它,发现最适合我的解决方案是不使用 async 和 await,而是使用 promise,因为共享多次返回。

root.navigator.share( title, url )
  .then(() => 
    /*
     this will be hit even if the message is logged
     due to iOS being a bit rubbish ATM
    */
  )
  .catch((err) => 
    const  message = ''  = err || ;
    if (message.indexOf('user denied permission') !== -1) 
      console.log(message);
    
  );

【讨论】:

您能分享一下您在点击时是如何解决的吗?

以上是关于Navigator.share 仅在 iOS 中工作一次,第二次单击会引发错误“用户代理不允许请求...”的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Google Maps Cordova ionic angular 仅在 Android 中工作而在 IOS 中为空白?

在 React 本机键盘仅在 IOS 的模态上显示,在 android 中工作正常

navigator.share 打开一个较小的菜单

Ios 应用程序只能在 Intranet 连接中工作

AlamoFire request() 仅在 viewDidLoad() 中工作

脚本仅在 Studio 中工作