修改Google“添加书签”书签以存储书签而不弹出窗口?

时间:2010-07-02 01:27:19

标签: javascript dom bookmarklet

小书签具有以下代码:

javascript:(function(){var%20a=window,b=document,c=encodeURIComponent,d=a.open("http://www.google.com/bookmarks/mark?op=edit&output=popup&bkmk="+c(b.location)+"&title="+c(b.title),"bkmk_popup","left="+((a.screenX||a.screenLeft)+10)+",top="+((a.screenY||a.screenTop)+10)+",height=420px,width=550px,resizable=1,alwaysRaised=1");a.setTimeout(function(){d.focus()},300)})();

弹出窗口中有验证功能和随机密钥:

<input type=submit name=btnA style="font-weight:bold" onclick="return _validate_add_bkmk(document.add_bkmk_form) && addp('btnA')"value="Add bookmark">

这是addp函数:

<script>function addp(p) {document.add_bkmk_form.action = document.add_bkmk_form.action + "&" + p;return true;}</script>

弹出窗口中的表单包含一个名为'sig'的随机值,它是弹出窗体提交操作的一部分:

<form name="add_bkmk_form" action="/bookmarks/mark?sig=2bbEz24YrH7rmG2yhwYeLQ&hl=en" method=post target="_self">

是否可以更改书签,以便自动提交表单以创建书签? - 很高兴点击书签,这样当前页面就会在后台添加书签,而无需经过弹出提交过程。

任何想法都非常感激。

2 个答案:

答案 0 :(得分:2)

朋友让我创建这样的书签,我做了,所以我将与其他人分享我的代码,他们最终在这里寻求现有的解决方案。 首先 - 上面提到的 sig 值是某种键/令牌,与用户登录的Google帐户相关联的签名(为了使用Google书签) - 并且它总是相同的值(对于一个帐户)。您必须找到此值并将其复制粘贴到下面的bookmarklet。只需查看此不需要的弹出页面的来源,然后搜索 / bookmarks / mark?sig = 或使用bookmarklet that shows hidden fields

我编写的第一个版本在新窗口(选项卡)中创建了一个简单的表单(如弹出窗口中的那个)并提交它。该窗口关闭后。这是代码:

javascript:(function(){
 var dloc = document.location;
 var dtitle = document.title;
 var code = '<html><head>
  <script src="https://www.google.com/bookmarks/history.js"></script></head><body>
  <script language="javascript">function addp(p) {document.add_bkmk_form.action = document.add_bkmk_form.action + "&" + p; return true;}</script>
  <form name="add_bkmk_form" action="https://www.google.com/bookmarks/mark?sig=_______________________&hl=pl" method=post target="_self">
  <input name=title type=text style="width:100%" id=bkmk_n value="' + dtitle + '">
  <input type="text" dir="ltr" style="width:100%" name="bkmk" id=bkmk_u value="' + dloc + '">
  <input name=labels autocomplete=off type=text style="width:100%" id=bkmk_label_1 value="">
  <input type="hidden" id="rbkmk_label_1" value=""><br>
  <textarea rows=4 style="width:100%" name=annotation style="font-size:smaller"></textarea>
  <input type=hidden name=sig value="_______________________">
  <input type=hidden name=prev value="/mark">
  <input type=submit name=btnA style="font-weight:bold" onclick="return _validate_add_bkmk(document.add_bkmk_form) && addp(\"btnA\")" value="Dodaj zakładkę">
  </form>
  <script language="javascript">document.getElementsByName("btnA")[0].click();</script>
  </body></html>';
 wnd=window.open("","wnd");
 with(wnd){
   document.write(code);
   document.close();
 } 
})();

而不是 _ __ _ __ _ __ _ _ 放置 sig 值。 我应该整理代码,删除样式,其他一些属性和未使用的字段,在“添加书签”按钮上使用英文标题,删除&amp; hl = pl 后缀等。也许只复制那些谷歌的 history.js 中使用的功能,但没有时间。

请求此书签的人并不完全喜欢它的行为 - 即它打开新标签/窗口片刻然后(自动)关闭它,但也有解决方案。

值得庆幸的是Google的表单也可以使用GET方法(而不是POST)发送,因此添加书签的整个操作可以通过打开如下所示的URL来执行:

https://www.google.com/bookmarks/mark?title=STACKOVERFLOW&bkmk=http%3A%2F%2Fstackoverflow.com%2F&labels=&annotation=&sig=___________________________&prev=%2Fmark&btnA=Dodaj+zak%C5%82adk%C4%99

- 再次将 sig 值替换为之前找到的值,然后将 Dodaj + zak%C5%82adk%C4%99 更改为添加书签或使用您的语言在谷歌界面中调用此按钮。在下面的bookmarklet中,我还将 bkmk 变量(带有站点地址)移动到URL的末尾,以便更好地处理&符号和其他一些特殊字符。

这个URL可以在新窗口/选项卡中打开,然后立即关闭,它将添加谷歌书签 - 但要实现这一点没有任何弹出窗口,新的窗口/标签我们必须使用小技巧并添加例如图像与<强> src 设置为此URL - 就像在下面的代码中完成的那样:

javascript:(function(){
  var gburl = 'https://www.google.com/bookmarks/mark?labels=&annotation=&sig=_____________&prev=%2Fmark&btnA=Add+bookmark&title=' +encodeURIComponent(document.title)+'&bkmk=' +encodeURIComponent(document.location);
  var f=window.frames;
  if(f.length>0 && Object.prototype.toString.call(document.body)==='[object HTMLFrameSetElement]'){
    f[0].document.body.innerHTML+='<img src="'+gburl+'" style="visibility:hidden" />';
  }
  else
  {
    document.body.innerHTML+='<img src="'+gburl+'" style="visibility:hidden" />';
  }
})();

图像添加在文档的末尾(如果页面使用框架集,则在第一帧的末尾)。它被设置为隐形,所以它不应该破坏任何东西。

令人惊讶的是,如果一切正常,谷歌服务回图像(明星) - 就像它专门为我的书签准备:-)所以我们可以用它来检查一切是否正确 - 通过检查例如图像的宽度或高度是否存在和等于15像素。添加图像后1500毫秒(使用 setTimeout())执行测试,因为浏览器必须首先下载图像并设置其属性。连接速度较慢,您可能需要增加此值,您可以更快地减少它。在Firefox 3.6,Opera,IE和Chrome中开发这个书签时我有一些没有超时的版本,使用的条件如下:!(typeof image.width ==='undefined')在某些情况下&gt; ; 0,在某些≥0或只是== 15 - 但几乎每个浏览器都必须检查不同的东西......带超时的版本似乎是最普遍的。所以我的最终代码是:

javascript:(function(){
  var gburl = 'https://www.google.com/bookmarks/mark?labels=&annotation=&sig=_____________&prev=%2Fmark&btnA=Add+bookmark&title=' +encodeURIComponent(document.title)+'&bkmk=' +encodeURIComponent(document.location);
  var f=window.frames;
  var gbimg=document.createElement('img');
  var using_frames=false;
  gbimg.src=gburl;
  gbimg.style.visibility='hidden'; 
  gbimg.id='gb_niepowtarzalnyID_2'; 

  function test_gbed(frames)
  {
    if(frames)
    {
      if(!window.frames[0].document.getElementById("gb_niepowtarzalnyID_2") || window.frames[0].document.getElementById("gb_niepowtarzalnyID_2").width!=15)
      {
        alert("Warning!!! - page probably hasn't been bookmarked (frames)");
      }
    }  
    else
    {
      if(!document.getElementById("gb_niepowtarzalnyID_2") || document.getElementById("gb_niepowtarzalnyID_2").width!=15)
      {
        alert("Warning!!! - page probably hasn't been bookmarked (no frames)");
      }
    }
  }

  if(f.length>0 && Object.prototype.toString.call(document.body)==='[object HTMLFrameSetElement]')
  {
    using_frames=true;
    /* f[0].document.body.innerHTML+='<img id="gb_niepowtarzalnyID_2" src="'+gburl+'" style="visibility:hidden" />'; */
    f[0].document.body.appendChild(gbimg);
  }
  else 
  {
    /* document.body.innerHTML+='<img id="gb_niepowtarzalnyID_2" src="'+gburl+'" style="visibility:hidden" />'; */
    document.body.appendChild(gbimg);
  }
  setTimeout(function(){test_gbed(using_frames)}, 1500);
})();

一些最终的想法,想法,注释:

不是只显示警报,而是可以从本主题中的第一个书签中添加代码,其中包含不需要的弹出窗口 - 因为错误通常意味着该用户未登录,然后弹出窗口将显示登录表单。 / p>

我已经在Firefox上进行了全面的测试,在上面提到的其他浏览器上,我从表面上看过它。

在上一个书签中,我用更优雅的方式替换了快速(但丑陋)的innerHTML修改,并将其附加到文档的正文中。

在某些页面上(例如:this one)Firefox甚至不会尝试下载添加到文档正文的图像(即使可见)。我找不到它的原因。例如,它在Opera上运行良好。

如果您的浏览器缓存安全内容(图片),您可能还需要在URL中添加时间戳( gburl = .......... +'&amp; myts ='+ new Date() .getTime(); ),如果你想再次添加书签页面。

不同的方法:创建用户脚本(对于带有Greasemonkey扩展的Firefox和Chrome,Opera)应该非常容易,只需在弹出窗口中自动提交表单 - 而不是使用修改过的书签。

要在书签工作完成后进行清理,可以从DOM中删除图像(在* test_gbed()*函数中)。

PS:我知道我可以优化和压缩我的bookmarklet的代码,但我这样做是为了更好的可读性。

答案 1 :(得分:0)

我不得不说不。由于其中包含令牌的页面(可能)与用户所在的任何页面(这是书签运行的上下文)位于不同的域上,因此跨站点限制将阻止书签从中删除令牌。页面。

因此,为了使您能够这样做,Google必须提供其他一些机制,但是任何允许您的书签在没有提示的情况下为页面添加书签的机制都可能允许不道德的网页也这样做。显然, 是不可取的(除了可能成为书签的垃圾邮件发送者),因此可能谷歌没有提供任何此类机制。

(如果bookmarklet以某种方式免于XSS限制,则可能。)