通过 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 && 'canShare' in navigator) /* ? */
)。你有一个网址来测试这个吗?
@DenverCoder9 这是一个 Nuxt 应用程序,不知道我应该如何运行它。最初我使用yarn dev
运行我的应用程序,但我什至尝试使用yarn generate
生成静态资产,然后运行yarn start
,但这也不起作用。
@user3718908 yarn dev
用于本地开发。如果你有target: static
,你应该yarn generate
和yarn start
确实。您甚至可以yarn generate
并将您的dist
目录直接放到这里:app.netlify.com/drop以上是关于通过 PWA 的社交媒体分享图片的主要内容,如果未能解决你的问题,请参考以下文章