如何禁用 <img> 标签的第三方 cookie?

Posted

技术标签:

【中文标题】如何禁用 <img> 标签的第三方 cookie?【英文标题】:How to disable third-party cookie for <img> tags? 【发布时间】:2019-01-04 01:44:57 【问题描述】:

是否有任何解决方案可以为使用 html5 或 javascript 技术从第三方域加载的图像禁用 cookie?

我正在寻找类似于&lt;iframe&gt; 标记的sandbox 属性、referrerpolicycrossorigin 属性的&lt;img&gt; 标记。

【问题讨论】:

@JeremyBanks,感谢您的 cmets。我的主要想法是显示来自第三方域的图像,但不允许他们设置/发送 cookie。将此视为自定义 Twitter 应用程序。 知道了。仅供参考 this question was linked from a meta discussion 关于 Stack Overflow 本身如何防止在网站上加载 Facebook 头像时将 cookie 和推荐人发送到 Facebook。 令人沮丧的是,似乎真的没有一种简单的、符合规范的、仅限前端的方式来执行此操作。 Jeremy Banks 指出,接受的答案并不能保证按规范工作。在图像上使用crossorigin="anonymous" 已失效,因为它将请求的mode 设置为“cors”,因此除非第三方服务器发出适当的access-control-allow-origin 标头,否则请求会返回网络错误。使用 fetchcredentials: 'omit', mode: 'no-cors' 可以让请求成功,但返回“不透明”响应。 我的最佳想法是使用fetch,然后将不透明响应缓存在@987654337 @ 然后使用服务工作者将不透明的响应作为图像src 提供?不过,我没有时间学习如何使用其中涉及的工具。 使用cloudimage.io/en/home怎么样?他们获取 URL 和图像大小并为您自动缩放。所以cookie不会成为问题,因为它访问了url? @JeremyBanks 【参考方案1】:

我无法真正确认下面的代码是否符合您的要求(因为我的浏览器、机器和网络上都有很多跟踪保护功能...)但只是添加另一个选项:您是否已经尝试过通过 javascript 加载图像? (我最初写的是“AJAX”而不是“javascript” - Samuel Willems,谢谢你告诉我我的错误。)

<html>
<script>
document.addEventListener('DOMContentLoaded', function () 
  var eArr=document.getElementsByTagName('img'),e;
  for (e of eArr) 
    if (e.hasAttribute('data-src')) 
      e.src=e.getAttribute('data-src');
    
  
);
</script>
<body>
<img src="" data-src="https://www.google.com/favicon.ico" >
</body>
</html>

【讨论】:

这是一个合理的建议,但代码 sn-p 并没有像你建议的那样实际使用 Ajax...【参考方案2】:

更新:此解决方法不再适用于:

火狐68 Safari 12.1.2

在对这个问题进行了几天的挑战后,我可以确认使用&lt;img&gt; 标签和任何当前可用的技术都无法做到这一点。

正确的方法是像 Google 一样使用无 cookie 代理服务器来处理图片,但目前这对我们来说太耗费资源了。

可接受的解决方法:

要禁用 cookie 将 &lt;img&gt; 替换为 &lt;iframesandbox&gt;; 要在 &lt;iframe&gt; 中显示图像,请使用带有内联 CSS 的 Data URI; 要模拟&lt;img&gt; 标记大小调整行为,请使用CSS background-size: cover 缩放图像,这允许将宽度和高度设置为适用于内部图像的&lt;iframe&gt;; 使用ARIA 属性将role="img"aria-label 指定为alt 替换。

示例:

<img   
     src="https://www.dtm.io/wp-content/uploads/2018/04/datamart-company.png" />

<iframe   aria-label="About company" role="img"
        frameborder="0" sandbox
        src="data:text/html,<style>bodybackground:url('https://www.dtm.io/wp-content/uploads/2018/04/datamart-company.png') center/cover no-repeat;padding:0;margin:0;overflow:hidden</style>"></iframe>

【讨论】:

这很有趣也很聪明,但我不确定它是否像描述的那样工作。我在 Firefox 中尝试了这个(首先从 sn-p 中删除原始 img 以避免混淆),在域上手动设置一些 cookie 之后,它们被包含在 iframe 的请求中:i.stack.imgur.com/s2P94.png 这似乎在 Chrome 中有效,但查看沙箱规范、功能政策以及我能找到的任何文档,我没有发现任何提及沙箱影响 cookie 的内容。它可能不是我们可以跨浏览器依赖的标准化行为。 @JeremyBanks,今天我在 macOS 上的 Chrome、Opera、Firefox 和 Safari、android 上的 Chrome 和 WebView 以及 ios 上的 Safari 上重新测试了这个解决方案。一切正常。我在我的宠物项目中使用这种方法大约一年 - anonace.com 我厌倦了一个简化的示例,您可以在 languid-barracuda.glitch.me 找到它,它似乎仍然在 Firefox 的请求中发送 cookie,正如您在 i.stack.imgur.com/GcuHC.png 和发布的屏幕截图中看到的那样更多。难道我做错了什么?它似乎不起作用。 向 Bugzilla 发布了一个问题 - bugzilla.mozilla.org/show_bug.cgi?id=1570980【参考方案3】:

在大多数情况下,这不是一个选项,但如果第三方图像使用包含 * 或您的主机的 Access-Control-Allow-Origin 标头提供,则可以使用 crossorigin="anonymous" 属性来禁用cookies。在这些情况下,您可能还应该添加 referrerpolicy="no-referrer" 以获得更大的隐私。

<img
  src="https://graph.facebook.com/official***/picture"
  crossorigin="anonymous"
  referrerpolicy="no-referrer"
/>

大多数网站不会设置此标头,您需要寻找替代品。但有些可以,比如 Facebook 的 API,这是针对这些情况的最简单的解决方案。

【讨论】:

这在问题和 cmets 中有所提及,但我认为应该在答案中明确写出,因为我在第一次阅读此主题时并不清楚。 不应该跨域只是污染图像,这意味着它仍然显示但不能通过画布读取其像素?【参考方案4】:

不是一个理想的解决方案,但您可以使用 iframe 加载图像,然后使用 css 技巧来屏蔽 iframe。

<iframe class="img-frame" sandbox src="https://www.google.com/favicon.ico" />

否则我不知道删除 cookie 的纯 HTML 方法。如果 iframe 的 cors 策略阻止它,我不相信您可以使用 JS 从父级更改 iframe cookie。

【讨论】:

感谢您的回答,这是我解决此问题的第一个方法。 祝你好运,如果你找到答案,请留下它,如果有可能知道它会很有趣 -1;这似乎不起作用(至少在 Chrome 中,它仍然会向 Google 发送 cookie - 请在 jsfiddle.net/mtpvuhj1 检查您的网络选项卡),以及在典型情况下(您不信任第三方,这就是全部您想要禁用第三方 cookie 的原因),它会造成不可接受的安全漏洞。仅仅因为今天的 URL 返回图像并不意味着它总是会;如果有一天第三方服务器决定返回一个包含网络钓鱼表单的 HTML 页面,那么通过采用这种方法,您会将该表单嵌入到您的页面中,这是非常糟糕的。

以上是关于如何禁用 <img> 标签的第三方 cookie?的主要内容,如果未能解决你的问题,请参考以下文章

如何在悬停时更改 <img> 标签的来源?

如何php给img标签里的src加链接

JS如何获取页面内所有的<img>标签元素?

如何设置html中img标签宽高相等

如何使用基本身份验证设置 <img> 标签

如何使用PHP给html<img>标签添加<div>?