本文介绍了Pinterest扩展如何从网页存储(临时)图像,然后在iframe中访问它们?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我一直在尝试创建一个 Pin It按钮(扩展Pinterest),就像Chrome扩展程序一样。 我试过的是在点击扩展程序时触发脚本,遍历网页上的所有可用图像,将其存储在localStorage 即可。现在我需要调用iframe(不同领域的课程)和访问这些图片。由于只能从同一个域访问本地存储,所以我很困惑Pinterest如何管理从网页(暂时而不是在他们的服务器上)存储所有图像,然后在iframe中使用它。 我也看到了PinIt Button扩展的代码,但我无法理解它,因为它太混乱/加密或其他。 我已经阅读了关于 chrome.storage api的内容,我还没有很好地理解它。我甚至不确定在这种情况下是否需要这样做。 (这是我第一次开发Chrome扩展)。任何人都可以提出一些建议,并指导我实现这一功能的最佳方式吗? 我已经在不使用< iframe> 的情况下完成了此扩展,但是我需要使用< iframe> 来完成。 编辑1:我不能在这里写完整的代码,但这里是流程/结构/我的尝试 我以 background.js chrome.browserAction.onClicked.addListener(function (tab){/ *这个fxn在点击扩展时触发* / chrome.tabs.executeScript(tab.id,{file:bookmarklet.js/ *调用这个文件* / })}); bookmarklet.js $ b jQuery('body')。append('< iframe class =vw_parentid =image-grabber-containersrc =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(){ //进行一些检查以确定需要存储哪些图像 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); //这给出NULL值 编辑2:根据DelightedD0D的评论和回答,我想解释此扩展程序的工作原理/应该如何工作 1.用户在任何网页上然后点击扩展程序 2.该网页上的所有图像都显示在iFrame 中3.用户可以从该iFrame中选择多个图像,然后将它们发布到我的网站 4. iFrame的原因:如果用户点击iFrame中的 POST IMAGE 按钮,并且他没有登录到我们的网站发布图片,他应该在相同的iFrame 5.如果不是iFrame,我将如何检查用户是否登录我的网站,因为我将无法读取不同域中不同域的会话/ cookie。 > 出于同样的原因,我相信(即使我不确定),pinterest也会在iFrame中显示图像 解决方案 TL; DR,链接到底部的扩展示例; 好的,您的问题有点宽泛,但我会尝试解释如果我想这样做,我会采取的方法。 首先,我会放弃iFrame。我看不出有什么理由在这里使用一个,我只是不喜欢他们。 我会: 有一个内容脚本被注入所有页面(或特定的一个,如果需要的话,不管) 脚本将有一个JavaScript类,它添加一个 chrome.runtime.onMessage.addListener 到该页面 此类将监听来自扩展程序的消息 消息将被发送到此类以触发函数并发回响应 ,例如 {pageAction:getImages} 等消息会触发 getImages 在注入的类中的函数 getImages 将获取所有图像并将它们发送回扩展名 在这里,我更喜欢使用像这样的东西编码为base64字符串的图像,而不是来自一大堆不同域和所有CORR的图像url ,链接保护......等。出于这个原因,我会让 getImages 对ajax调用 encodeImagesToBase64.php 传递一个图像数组的服务器网址。 encodeImagesToBase64.php 会返回一个base64图片数组,然后发送给该扩展。 现在扩展名中包含一组base64图像,Id将它们保存到扩展程序的存储区中的 chrome.storage.local 。 现在您可以在弹出窗口中显示它们,将它们显示在新标签中进行编辑,或者其他任何内容 如果您想在页面中,只需在我们制作的JavaScript侦听器类中创建一个函数,然后发送一条消息给它并显示图像 为了让你开始,这里是一个JavaScript监听器类,我使用它来在我的扩展中做类似的事情。 (请注意,这依赖于John Resig的简单JavaScript继承,我强烈建议在撰写时使用它类) //重要提示:您必须通过chrome:// extensions // //重新加载您的扩展程序浏览器选项卡,以便更改此文件被看到! var PageActionListener = Class.extend({ / ** *)这个类一旦被注入网页 *,它会监听消息从一个扩展 *消息必须通过{pageAction:someAction,...} *其中someAction应该映射到这个类中的函数 *响应应该采用 * {success:true,pageAction:someAction,data:someData,...} * / attachListener:function(){ / ** *将一个chrome消息监听器附加到当前页面 *,这允许扩展从 *页面的上下文中调用该类中的函数 *,并通过这些函数接收响应消息 * / var _this = this; //监听弹出消息 chrome.runtime.onMessage.addListener(函数(msg,sender,extensionCallback){ //首先,验证消息链接到一个函数 if(msg.pageAction){ //然后确定它在这个类中的合法函数 if(typeof _this [msg.pageAction] == =function){ //调用该函数 _this [msg.pageAction](msg,function(response){ extensionCallback(response); }); } else extensionCallback({success:false,msg:msg,error:Action not found}); 返回true; } }); }, getImages:function(msg,callback){ / ** *遍历DOM查找图像并将它们返回 *作为base64数组字符串 * @param object msg触发此操作的消息 * @param function callback当下面的操作完成时要调用的函数 *传递回调从页面收集的图像 * / var images = []; var $ images = $('img'); $ images.each(function(){ var url = this.src; images.push(url); }); //将图片转换为base64 $ .ajax({类型:POST, url:https://somedomain.com/shared-resources/php/ encodeImagesToBase64.php,//你需要将它更新到你的路径 data:{url:images}, success:function(response){ response.msg = msg; 将响应发回给扩展 callback(response); }, error:function(xhr,status,error){ callback({success: false,msg:msg,error:error.Message})} }); }, //添加其他需要在这里被扩展名调用的函数}); 这里是 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'=>'错误:No images to encode']);; } 下面是一个示例扩展,kindof做你想要的。 它需要一种方法去满足您的实际需求,但它应该足以让您了解上面提出的概念和方法。 注意 >示例扩展使用服务器上托管的 encodeImagesToBase64.php 的副本,您需要托管自己的主机并使用其路径更新ajax调用。我现在就把它留下来,这样你就可以测试它了,但是不要指望它会永远存在:) I've been trying to create a Pin It button (extension of Pinterest) like chrome extension. What i tried is firing a script when extension is clicked which can iterate through all available images on a webpage, store it in localStorage. Now i need to call an iframe (different domain ofcourse) and access these images. Since one can access localstorage only from same domain, i'm quite confused how Pinterest manages to store all images from a web page (temporarily and not on their server) and then use it in an iframe.I also saw the code of PinIt Button extension but i can't understand a thing from it as it is too much obfuscated/encrypted or whatever.I've read about chrome.storage api and i haven't been able to understand it quite well. I'm not even sure if this is the thing i need to do in this case. (This is the first time i'm developing a chrome extension). Can anybody please throw some light on this and guide me the best possible way to achieve this functionality?P.S. I've completed this extension without using <iframe> however i need to do it with <iframe>.EDIT 1: I can't write complete code here but here is the flow/structure/my attemptsI start with background.jschrome.browserAction.onClicked.addListener(function (tab) { /*This fxn fires when extension is clicked*/ chrome.tabs.executeScript(tab.id, { "file": "bookmarklet.js"/*Calls this file*/ })});In 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);Now in FileToBeInjectedInIframe.phpvar abcde = localStorage.getItem('myLocalImgs');console.log(abcde);//This gives NULL valueEDIT 2: As per comments and answer by DelightedD0D, i want to explain How this extension works/should work1. User is on any webpage and then clicks the extension2. All the images available on that webpage are displayed in an iFrame3. User can select multiple images from this iFrame and then post them to my website4. Reason for iFrame: If user clicks on POST IMAGE button available in iFrame and he is not logged into our website for posting the image, he should see a login popup in the same iFrame5. If not iFrame, how would i check if the user is logged in my website as i won't be able to read session/cookie of a different domain on a different domain.For same reasons i believe (i'm not sure though), pinterest also display images in an iFrame 解决方案 TL;DR, link to an example extension at the bottom ;)Ok, your question is a bit broad but I'll try to explain the approach I would take if I wanted to do this.First, I'd drop the iFrame. I can't see any reason to use one here and I just dont like them personally.I would:have a content script that is injected into all pages (or specific one if needed, whatever)the script would have a javascript class that adds a chrome.runtime.onMessage.addListener to the pagethis class would listen for messages from the extensionmessages would be sent to this class to trigger functions and send back a responsefor example a message like {pageAction:"getImages"} would trigger the getImages function in the injected classgetImages would get all the images and send them back to the extensionOne note here, I prefer to work with images encoded as base64 strings with stuff like this rather than image urls from a whole bunch of different domains and all the CORRs, link protection,....etc. For that reason, I would have the getImages make an ajax call to encodeImagesToBase64.php a server passing an array of image urls. encodeImagesToBase64.php would return an array of base64 images which are then sent to the extension.Now that the extension has an array of base64 images, Id save them to chrome.storage.local in the extension's storage area.Now you can show them in the popup, show them in a new tab for editing, or whateverIf you want to show them on the page in an overlay, just make a function to do that in the javascript listener class we made and send a message to it with the images to displayTo get you started, here is a javascript listener class I use to do similar things in my extensions.(note that this relies on John Resig's Simple JavaScript Inheritance which I highly recommend using when writing Classes )// 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});And here is the contents of encodeImagesToBase64.php to convert the images to base64:<?phpif (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.It'll need a ways to go to meet your actual needs but, it should be enough for you to understand the concepts and the approach Ive proposed above.NOTE the example extension uses a copy of encodeImagesToBase64.php that is hosted on my server, you'll need to host your own and update the ajax call with the path to it. Ill leave mine up for now so you can test it out, but dont count on it being around forever :) 这篇关于Pinterest扩展如何从网页存储(临时)图像,然后在iframe中访问它们?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!