草庐IT

javascript - 从 Chrome 上的 Greasemonkey 脚本将 JS 函数注入(inject)页面

coder 2023-07-05 原文

我有一个在 Firefox 和 Opera 中运行良好的 Greasemonkey 脚本。然而,我很难让它在 Chrome 中运行。问题是将一个函数注入(inject)到页面中,该函数可以被页面中的代码调用。这是我目前所做的:

首先,我获得了对 unsafeWindow 的帮助引用对于火狐。这使我可以为 FF 和 Opera(我认为还有 Chrome)使用相同的代码。

var uw = (this.unsafeWindow) ? this.unsafeWindow : window;

接下来,我将一个函数注入(inject)到页面中。它实际上只是一个非常薄的包装器,除了在我的 GM 脚本的上下文中调用相应的函数外什么都不做:

uw.setConfigOption = function(newValue) {
    setTimeout(setConfigOption, 0, newValue);
}

然后,我的脚本中就有相应的函数:

setConfigOption = function(newValue) {
    // do something with it, e.g. store in localStorage
}

最后,我将一些 HTML 注入(inject)到页面中,其中包含调用该函数的链接。

var p = document.createElement('p');
p.innerHTML = '<a href="javascript:setConfigOption(1)">set config option to 1</a>';
document.getElementById('injection-point').appendChild(p);

总结一下: 在 Firefox 中,当用户单击那个注入(inject)的链接时,它将在 unsafeWindow 上执行函数调用,然后触发超时,在我的 GM 脚本的上下文中调用相应的函数,然后进行实际处理。 (如果我在这里错了,请纠正我。)

在 Chrome 中,我只收到“ Uncaught ReferenceError :setConfigOption 未定义”错误。事实上,在控制台中输入“window.setConfigOption”会产生“undefined”。在 Firebug 和 Opera 开发人员控制台中,该函数就在那里。

也许还有另一种方法可以做到这一点,但我的一些函数是由页面上的 Flash 对象调用的,我认为这使得我必须在页面上下文中拥有函数。

我快速浏览了 alternatives to unsafeWindow在 Greasemonkey wiki 上,但它们看起来都很丑陋。我在这里完全走错了路还是应该更仔细地研究这些?

解决方案: 我遵循了 Max S.' advice它现在可以在 Firefox 和 Chrome 中使用。因为我需要对页面可用的函数必须回调到常规函数中,所以我将整个脚本移到了页面中,即它完全包含在他称为“main()”的函数中。

为了让那个 hack 的额外丑陋变得更加可以忍受,我现在至少可以放弃使用 unsafeWindow 和 wrappedJSObject。

我还是没能得到 content scope runner来自 Greasemonkey 维基工作。它应该做同样的事情并且看起来执行得很好,但我的功能永远无法访问 <a>例如,页面中的元素。我还没有弄清楚为什么会这样。

最佳答案

与 Chrome 页面上运行的代码进行通信的唯一方法是通过 DOM,因此您必须使用 hack,例如插入 <script>用你的代码标记。请注意,如果您的脚本需要在页面上的其他所有内容之前运行,这可能会证明存在错误。

编辑 the Nice Alert extension 是这样的这样做:

function main () {
  // ...
  window.alert = function() {/* ... */};
  // ...
}

var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main +')();'));
(document.body || document.head || document.documentElement).appendChild(script);

关于javascript - 从 Chrome 上的 Greasemonkey 脚本将 JS 函数注入(inject)页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2303147/

有关javascript - 从 Chrome 上的 Greasemonkey 脚本将 JS 函数注入(inject)页面的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  3. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  4. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  5. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  6. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  7. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  8. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

  9. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  10. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

随机推荐