通过 PWA 的社交媒体分享图片

Posted

技术标签:

【中文标题】通过 PWA 的社交媒体分享图片【英文标题】:Share image via social media from PWA 【发布时间】:2021-07-13 12:40:30 【问题描述】:

在我的 Nuxt PWA 中,我有一个使用 this package 将我的 html 转换为 Canvas 的函数。生成的图像以 64 为基数。现在我希望能够通过以下方式共享该图像:Whatsapp、Facebook、电子邮件、Instagram 等。我找到了几个包,但它们似乎都不支持仅共享文件 URL 和文本。

这是我的分享功能:

shareTicket(index) 
  html2canvas(this.$refs['ticket-' + index][0], 
    backgroundColor: '#efefef',
    useCORS: true, // if the contents of screenshots, there are images, there may be a case of cross-domain, add this parameter, the cross-domain file to solve the problem
  ).then((canvas) => 
    let url = canvas.toDataURL('image/png') // finally produced image url

    if (navigator.share) 
      navigator.share(
        title: 'Title to be shared',
        text: 'Text to be shared',
        url: this.url,
      )
    
  )

当我取出 if (navigator.share) 条件时,我在控制台中收到错误消息,指出 navigator.share 不是函数。我在某处读到它只适用于 HTTPS,所以我上传到我的登台服务器并尝试过,但仍然遇到同样的错误。

为了清楚起见,我希望能够共享生成的图像本身而不是 URL。

【问题讨论】:

如果你把这些都写在if (process.client) // insert your whole code here 会发生什么?还有,这个好像主要用在手机上,你是在手机上试过还是只在桌面上用过? 抱歉,我不知道 process.client 是什么意思,如果同时适用于移动设备和桌面设备,我已经在两者上都尝试过了,但它不起作用。 这是来自 Nuxt 文档,基本上是说代码不应该在服务器上运行。 nuxtjs.org/docs/2.x/internals-glossary/context 按照 MDN 的文档,我实现了使演示正常工作:developer.mozilla.org/en-US/docs/Web/API/Navigator/share 你想要和这个页面一样的结果,对吧? 当我将代码包装在 if (process.client) 中时,我仍然收到错误 navigator.share is not a function。不知道它不能与服务器一起使用,不知道如何运行我的应用程序。是的,我希望能够分享您分享的链接中描述的文件。 对不起什么包?我很困惑。 【参考方案1】:

告诉我这个网址是否适合你:https://nuxt-share-social-media.netlify.app 如果是这样,你可以在这里找到 Github repo:https://github.com/kissu/so-share-image-bounty

代码是

<template>
  <div>
    <div id="capture" ref="element" style="padding: 10px; background: #f5da55">
      <h4 style="color: #000">Hello world!</h4>
    </div>

    <br />
    <br />
    <button @click="share">share please</button>
  </div>
</template>

<script>
import html2canvas from 'html2canvas'

export default 
  methods: 
    share() 
      // iife here
      ;(async () => 
        if (!('share' in navigator)) 
          return
        
        // `element` is the HTML element you want to share.
        // `backgroundColor` is the desired background color.
        const canvas = await html2canvas(this.$refs.element)
        canvas.toBlob(async (blob) => 
          // Even if you want to share just one file you need to
          // send them as an array of files.
          const files = [new File([blob], 'image.png',  type: blob.type )]
          const shareData = 
            text: 'Some text',
            title: 'Some title',
            files,
          
          if (navigator.canShare(shareData)) 
            try 
              await navigator.share(shareData)
             catch (err) 
              if (err.name !== 'AbortError') 
                console.error(err.name, err.message)
              
            
           else 
            console.warn('Sharing not supported', shareData)
          
        )
      )()
    ,
  ,

</script>

灵感来自@denvercoder9!


关于答案的更多信息

我使用了an IIFE,因为我不确定整个事情是如何工作的,但它在method 上下文中效果很好! 我添加了一个缺少的 async,因为 ESlint 并且以防你想在之后做点什么 我使用了$refs,因为这是您应该在 Vue 生态系统中选择 DOM 的特定部分的方式 为了简单起见,我删除了一些内容,在 Netlify 上托管了一些简单的 HTTPS,并在 Chrome (v91) 上对其进行了测试,效果非常好! 这里又是the link Web Share API 的 MDN 文档。

兼容性

这是我对浏览器的体验(在 MDN 示例和我的应用上测试,结果完全相同)

where working
iPad chrome yes
iPad firefox yes
iPad safari yes
windows chrome yes
windows firefox no
android chrome yes
android firefox no
desktop linux chrome no
desktop linux firefox no

对我来说,这是一项仅限移动设备的功能(例如 Android 设备)。但看起来甚至一些桌面浏览器也在处理这个问题。我不得不承认,即使在 Windows 上看到这一项工作,我也感到非常惊讶。 这是来自 Google 的一篇有趣的帖子,与这种兼容性相关:https://web.dev/web-share/#browser-support

再次阅读 MDN,它说

Web Share API 的 navigator.share() 方法调用设备的原生共享机制。

所以,我猜“(桌面)设备”大多不支持 Share API。

TLDR:这完全按预期工作,但到目前为止兼容性真的很差。

【讨论】:

非常感谢您抽出宝贵时间。我在运行 BigSur 的 Mac 上的最新稳定版本的 firefox、chrome 和 edge 中都尝试了此方法,但仍然无法正常工作。但是,当我在 Safari 中尝试它时,它起作用了。我也在我的手机上试过,它只适用于 chrome 而不是 firefox。不知道这里发生了什么。 所以看起来我的代码有效:-) 这是screenshot,我在桌面 Safari 上进行了测试。 Microsoft Edge(基于 Chromium 的变体)在桌面上也支持 API。它也将很快登陆 Chrome 上的 macOS 和 Windows。它还可以在 Chrome OS 上运行。 @DenverCoder9 是的,这可能只是时髦的支持 + 拥有经过适当验证的 SSL 证书来尝试。【参考方案2】:

我在我的一个应用程序中的share() 函数中有以下代码的变体,如果在客户端上执行它可以正常工作。

const share = async() => 
  if (!('share' in navigator)) 
    return;
  
  // `element` is the HTML element you want to share.
  // `backgroundColor` is the desired background color.
  const canvas = await html2canvas(element, 
    backgroundColor,
  );
  canvas.toBlob(async (blob) => 
    // Even if you want to share just one file you need to 
    // send them as an array of files.
    const files = [new File([blob], 'image.png',  type: blob.type )];
    const shareData = 
      text: 'Some text',
      title: 'Some title',
      files,
    ;
    if (navigator.canShare(shareData)) 
      try 
        await navigator.share(shareData);
       catch (err) 
        if (err.name !== 'AbortError') 
          console.error(err.name, err.message);      
        
      
     else 
      console.warn('Sharing not supported', shareData);            
    
  );
;

【讨论】:

不起作用。当我取出条件时,我得到 TypeError: navigator.canShare is not a function。不确定我是否需要 Vue/Nuxt 特定的解决方案。 你确定你在客户端上运行这个(也就是说,在浏览器中,而不是在服务器上)?此外,并非所有浏览器都支持 Web Share Level 2 API,因此您需要对此进行功能检测 (if ('share' in navigator &amp;&amp; 'canShare' in navigator) /* ? */ )。你有一个网址来测试这个吗? @DenverCoder9 这是一个 Nuxt 应用程序,不知道我应该如何运行它。最初我使用yarn dev 运行我的应用程序,但我什至尝试使用yarn generate 生成静态资产,然后运行yarn start,但这也不起作用。 @user3718908 yarn dev 用于本地开发。如果你有target: static,你应该yarn generateyarn start 确实。您甚至可以yarn generate 并将您的dist 目录直接放到这里:app.netlify.com/drop

以上是关于通过 PWA 的社交媒体分享图片的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 画布 - 将保存的图像分享到社交媒体

oppo+reno6图片怎么分享?

社交媒体在页面外分享特定内容

WordPress 自定义帖子特色图片、标题和内容社交媒体共享

如何从社交媒体缩略图中排除 Jumbotron 图像?

Firebase 动态链接不会在社交媒体中预览图片