Pinterest 扩展如何(临时)存储网页中的图像,然后在 iframe 中访问它们?
Posted
技术标签:
【中文标题】Pinterest 扩展如何(临时)存储网页中的图像,然后在 iframe 中访问它们?【英文标题】:How Pinterest extension store (temporarily) images from a web page and then access them in an iframe? 【发布时间】:2016-08-24 03:47:33 【问题描述】:我一直在尝试创建一个 Pin It button(Pinterest 的扩展),例如 chrome 扩展。 我尝试过的是在单击扩展程序时触发一个脚本,该脚本可以遍历网页上的所有可用图像,将其存储在 localStorage。现在我需要调用 iframe(当然是不同的域) 并访问这些图像。由于只能从同一个域访问本地存储,我很困惑 Pinterest 如何设法存储来自网页的所有图像(暂时而不是在他们的服务器上)然后在 iframe 中使用它。
我还看到了 PinIt Button 扩展的代码,但我无法理解其中的任何内容,因为它被太多混淆/加密或其他任何东西。
我已经阅读了chrome.storage
api,但我还不能很好地理解它。我什至不确定这是否是我在这种情况下需要做的事情。 (这是我第一次开发 chrome 扩展)。任何人都可以对此有所了解并指导我实现此功能的最佳方法吗?
附:我已在不使用 <iframe>
的情况下完成了此扩展,但我需要使用 <iframe>
。编辑 1: 我无法在此处编写完整的代码,但这里是流程/结构/我的尝试
我从background.js
开始
chrome.browserAction.onClicked.addListener(function (tab) /*This fxn fires when extension is clicked*/
chrome.tabs.executeScript(tab.id,
"file": "bookmarklet.js"/*Calls this file*/
)
);
在bookmarklet.js
:
jQuery('body').append('<iframe class="vw_parent" id="image-grabber-container" src="" style="height: 100% !important; width: 100% !important; position: fixed !important; margin: 0% auto !important; background: rgba(17, 17, 17, 0.9) !important; left: 0 !important; right: 0 !important; z-index: 999999999 !important; top: 0% !important;"></iframe>');
jQuery('img').each(function()
//do some checks to determine what images need to be stored
var allImgs = jQuery(this);
localStorage.setItem('myLocalImgs', allImgs);
)
vwgrid = "https://mydomain/FileToBeInjectedInIframe.php";
jQuery('#image-grabber-container').attr('src', vwgrid);
现在在FileToBeInjectedInIframe.php
var abcde = localStorage.getItem('myLocalImgs');
console.log(abcde);
//This gives NULL value
编辑 2: 根据 cmets 和 DelightedD0D 的回答,我想解释 此扩展如何工作/应该如何工作 1.用户在任何网页上,然后点击扩展 2. 该网页上所有可用的图像都显示在 iFrame 3. 用户可以从这个 iFrame 中选择多个图像,然后将它们发布到我的网站 4. 使用 iFrame 的原因:如果用户点击 iFrame 中的 POST IMAGE 按钮,并且他没有登录我们的网站发布图像,他应该会在同一个 iFrame 中看到一个登录弹出窗口 5. 如果不是 iFrame,我将如何检查用户是否登录了我的网站,因为我将无法在不同域上读取不同域的会话/cookie。出于同样的原因,我相信(不过我不确定),pinterest 也会在 iFrame 中显示图像
【问题讨论】:
Chrome 扩展可以通过多种方式访问任何域的本地存储。但是,您最好将信息存储在Chrome.storage 为了提供更多指导,我们需要准确了解您在做什么。例如,为什么需要 iframe?你在做什么?为什么不只使用图像标签? iframe 到底在哪里?在popup.html中,在扩展打开的一个窗口中,注入到当前页面? 嗯,好吧,这给了我一个更好的画面。 FileToBeInjectedInIframe.php 怎么样?你到底在那儿做什么?我假设有一些服务器处理正在进行,因为它是一个 php 页面? 还没有,但是是的,我稍后要做一些登录的事情,所以我把它做成了一个 php 文件。基本上我会将此 iframe 显示为全屏透明覆盖,其中包含父页面中的所有图像,然后用户可以从中选择多个图像,然后将其发布到某个地方(我们自己的服务器)。 好的,给我一点答案 【参考方案1】:TL;DR,链接到底部的示例扩展;)
好的,您的问题有点宽泛,但如果我想这样做,我会尝试解释我会采取的方法。
首先,我会删除 iFrame。我看不出有任何理由在这里使用它们,而且我个人不喜欢它们。
我愿意:
有一个内容脚本被注入到所有页面(或特定的,如果需要的话,无论如何) 脚本将有一个 javascript 类,该类将chrome.runtime.onMessage.addListener
添加到页面
这个类会监听来自扩展的消息
将向此类发送消息以触发函数并返回响应
例如像pageAction:"getImages"
这样的消息会触发注入类中的getImages
函数
getImages
将获取所有图像并将它们发送回扩展程序
这里需要注意的是,我更喜欢使用带有类似这样的东西的 base64 字符串编码的图像,而不是来自一大堆不同域的图像 url 以及所有 CORR、链接保护等。出于这个原因,我会让getImages
对encodeImagesToBase64.php
进行ajax 调用,服务器会传递一组图像url。 encodeImagesToBase64.php
将返回一个 base64 图像数组,然后将其发送到扩展。
chrome.storage.local
。
现在您可以在弹出窗口中显示它们,在新选项卡中显示它们以进行编辑,或其他任何方式
如果您想在页面上以叠加层的形式显示它们,只需在我们创建的 javascript 侦听器类中创建一个函数来执行此操作,并向其发送带有要显示的图像的消息
为了帮助您入门,这里有一个 javascript 侦听器类,我用它来在我的扩展程序中做类似的事情。
(请注意,这依赖于 John Resig 的 Simple JavaScript Inheritance,我强烈建议在编写类时使用它)
// IMPORTANT NOTE you must reload your extension via chrome://extensions
// AND reload the browser tab in order for changes to this file to be seen!!
var PageActionListener = Class.extend(
/**
* This class is meant to be injected into a webpage
* once there, it listens for messages from an extension
* messages must pass like pageAction:"someAction", ...
* where someAction should map to a function in this class
* responses should take the form
* success:true, pageAction:"someAction", data:"someData", ...
*/
attachListener: function()
/**
* Attaches a chrome message listener to the current page
* this allows the extension to call
* the functions in this class from the context of the page
* and receive responses from those functions via messaging
*/
var _this=this;
// Listen for messages from the popup
chrome.runtime.onMessage.addListener(function (msg, sender, extensionCallback)
// First, validate the message links to a function
if (msg.pageAction)
// then make sure its a legit function in this class
if(typeof _this[msg.pageAction] === "function")
// call that fucntion
_this[msg.pageAction](msg,function(response)
extensionCallback(response);
);
else extensionCallback(success:false,msg:msg,error:"Action not found");
return true;
);
,
getImages:function(msg,callback)
/**
* Traverses the DOM looking for images and returning them
* as an array of base64 strings
* @param object msg The message that triggered this action
* @param function callback A function to be called when the action below is complete
* passes to callback the images gathered from the page
*/
var images = [];
var $images= $('img');
$images.each(function()
var url = this.src;
images.push(url);
);
// convert images to base64
$.ajax(
type: "POST",
url: "https://somedomain.com/shared-resources/php/encodeImagesToBase64.php", // you'll need to update this to your path
data: urls:images,
success: function(response)
response.msg=msg;
send the response back to the extension
callback(response);
,
error: function(xhr, status, error)
callback(success:false,msg:msg,error:error.Message)
);
,
// add other functions that need to be called by the extension here
);
这是encodeImagesToBase64.php
的内容,用于将图像转换为base64:
<?php
if (isset($_POST['urls']) )
$imageStrings=[];
foreach($_POST['urls'] as $url)
$imageStrings[]=base64_encode(file_get_contents($url));
echo json_encode(['success'=>true,'images'=>$imageStrings]);
else
echo json_encode(['success'=>false,'error'=>'Error: No images to encode']);;
Here is an example extension that kindof does what you want.
它需要一种方法来满足您的实际需求,但是,它应该足以让您理解我上面提出的概念和方法。
注意示例扩展使用了我的服务器上托管的encodeImagesToBase64.php
的副本,您需要自己托管并使用其路径更新 ajax 调用。我暂时搁置我的,这样你就可以测试它了,但不要指望它会永远存在:)
【讨论】:
@damio 不正确。如果您将来自另一个域的图像加载到画布中,toDataURL()
将不起作用。 See this question 你必须使用服务器端处理(除非你处理的每个图像都来自支持 CORS 并启用它的域,这里肯定不是这种情况)
首先,感谢您的回答,我非常感谢您的帮助,但是正如我在问题中提到的,我已经在没有 iframe 的情况下实现了此功能,但是我需要使用 iframe 来实现。其次,为什么我需要对图像进行编码,我实际上只需要 URL 并且太临时了,因为我将使用该 URL 来发布该图像。第三,这种 消息传递 方法是否可以在 iFrame 中使用(如果是,那么我的 iFrame 将无法从不同的域读取本地存储)。
请检查我的EDIT 2
@TusharShukla 如果您想要的只是 url,只需跳过 base64 编码并发回 url。就 iframe 而言,不需要它。只需在弹出窗口中提供您的 UI,或者您提到的注入覆盖。让 pageActionListener 或 popup.html 中的 js 通过 ajax 来回发送您需要的任何数据,就像我设置它来编码图像一样。这只是向您展示,您可以在没有 iframe 的情况下完成所有这些事情。它们在这里没用
我也在尝试你的扩展,但它给了我errors以上是关于Pinterest 扩展如何(临时)存储网页中的图像,然后在 iframe 中访问它们?的主要内容,如果未能解决你的问题,请参考以下文章
当点击扩展程序时,pinterest 如何在任何网站上加载 iframe?
Pinterest 数据切分:解惑快速扩展 MySQL 的数据量
如何使用带有 Pinterest.sharextension 的 UIActivityViewController 设置 Pinterest sourceURL 和描述