Javascript Chrome扩展修改页面的脚本包含和JS
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10075620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Chrome extension to modify page's script includes and JS
提问by Herms
I work on a javascript library that customers include on their site to embed a UI widget. I want a way to test dev versions of the library live on the customer's site without requiring them to make any changes to their code. This would make it easy to debug issues and test new versions.
我开发了一个 javascript 库,客户将其包含在他们的网站上以嵌入 UI 小部件。我想要一种在客户站点上实时测试库的开发版本的方法,而无需他们对其代码进行任何更改。这将使调试问题和测试新版本变得容易。
To do this I need to change the script include to point to my dev server, and then override the load() method that's called in the page to add an extra parameter to tell it what server to point to when making remote calls.
为此,我需要将脚本包含更改为指向我的开发服务器,然后覆盖在页面中调用的 load() 方法以添加一个额外的参数来告诉它在进行远程调用时指向哪个服务器。
It looks like I can add JS to the page using a chrome extension, but I don't see any way to modify the page before it's loaded. Is there something I'm missing, or are chrome extensions not allowed to do this kind of thing?
看起来我可以使用 chrome 扩展将 JS 添加到页面中,但是在加载页面之前我看不到任何修改页面的方法。是否有我遗漏的东西,或者不允许 chrome 扩展做这种事情?
回答by apsillers
I've done a fair amount of Chrome extension development, and I don't think there's any way to edit a page source before it's rendered by the browser. The two closest options are:
我已经完成了大量的 Chrome 扩展程序开发,我认为在浏览器呈现之前没有任何方法可以编辑页面源代码。最接近的两个选项是:
Content scriptsallow you to toss in extra JavaScript and CSS files. You might be able to use these scripts to rewrite existing script tags in the page, but I'm not sure it would work out, since any script tags visible to your script through the DOM are already loaded or are being loaded.
WebRequestallows you to hiHyman HTTP requests, so you could have an extension reroute a request for
library.js
tolibrary_dev.js
.
内容脚本允许你加入额外的 JavaScript 和 CSS 文件。您或许可以使用这些脚本来重写页面中现有的脚本标签,但我不确定它是否可行,因为通过 DOM 对您的脚本可见的任何脚本标签都已经加载或正在加载。
WebRequest允许您劫持 HTTP 请求,因此您可以通过扩展将请求重新路由
library.js
到library_dev.js
.
Assuming your site is www.mysite.com and you keep your scripts in the /js directory:
假设您的站点是 www.mysite.com 并且您将脚本保存在 /js 目录中:
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
if( details.url == "http://www.mysite.com/js/library.js" )
return {redirectUrl: "http://www.mysite.com/js/library_dev.js" };
},
{urls: ["*://www.mysite.com/*.js"]},
["blocking"]);
The HTML source will look the same, but the document pulled in by <script src="library.js"></script>
will now be a different file. This should achieve what you want.
HTML 源代码看起来相同,但拉入的文档<script src="library.js"></script>
现在将是不同的文件。这应该达到你想要的。
回答by Lars Christian Jensen
Here's a way to modify content before it is loaded on the page using the WebRequestAPI. This requires the content to be loaded into a string variable before the onBeforeRequest listener returns. This example is for javascript, but it should work equally well for other types of content.
这是一种在使用WebRequestAPI将内容加载到页面之前修改内容的方法。这需要在 onBeforeRequest 侦听器返回之前将内容加载到字符串变量中。此示例适用于 javascript,但对于其他类型的内容应该同样适用。
chrome.webRequest.onBeforeRequest.addListener(
function (details) {
var javascriptCode = loadSynchronously(details.url);
// modify javascriptCode here
return { redirectUrl: "data:text/javascript,"
+ encodeURIComponent(javascriptCode) };
},
{ urls: ["*://*.example.com/*.js"] },
["blocking"]);
loadSynchronously() can be implemented with a regular XMLHttpRequest. Synchronous loading will block the event loop and is deprecatedin XMLHttpRequest, but it is unfortunately hard to avoid with this solution.
loadSynchronously() 可以使用常规 XMLHttpRequest 实现。同步加载会阻塞事件循环,并在 XMLHttpRequest 中被弃用,但不幸的是,使用此解决方案很难避免。
回答by Tobia
You might be interested in the hooks available in the Opera browser. Opera used to have* very powerful hooks, available both to User JavaScript files (single-file things, very easy to write and deploy) and Extensions. Some of these are:
您可能对 Opera 浏览器中可用的钩子感兴趣。Opera 曾经拥有*非常强大的钩子,可用于用户 JavaScript 文件(单文件的东西,非常容易编写和部署)和扩展。其中一些是:
BeforeExternalScript:
在ExternalScript之前:
This event is fired when a script element with a src attribute is encountered. You may examine the element, including its src attribute, change it, add more specific event listeners to it, or cancel its loading altogether.
当遇到具有 src 属性的脚本元素时会触发此事件。你可以检查元素,包括它的 src 属性,改变它,向它添加更多特定的事件监听器,或者完全取消它的加载。
One nice trick is to cancel its loading, load the external script in an AJAX call, perform text replacement on it, and then re-inject it into the webpage as a script tag, or using eval.
一个不错的技巧是取消其加载,在 AJAX 调用中加载外部脚本,对其执行文本替换,然后将其作为脚本标签重新注入网页,或使用 eval。
window.opera.defineMagicVariable:
window.opera.defineMagicVariable:
This method can be used by User JavaScripts to override global variables defined by regular scripts. Any reference to the global name being overridden will call the provided getter and setter functions.
用户 JavaScript 可以使用此方法来覆盖由常规脚本定义的全局变量。对被覆盖的全局名称的任何引用都将调用提供的 getter 和 setter 函数。
window.opera.defineMagicFunction:
window.opera.defineMagicFunction:
This method can be used by User JavaScripts to override global functions defined by regular scripts. Any invocation of the global name being overridden will call the provided implementation.
用户 JavaScript 可以使用此方法来覆盖由常规脚本定义的全局函数。任何对被覆盖的全局名称的调用都将调用提供的实现。
*: Opera recently switched over to the Webkit engine, and it seems they have removed some of these hooks. You can still find Opera 12 for download on their website, though.
*:Opera 最近切换到 Webkit 引擎,似乎他们已经删除了其中的一些钩子。不过,您仍然可以在他们的网站上找到 Opera 12 以供下载。
回答by KInGcC
I had an idea, but I didn't try it, but it worked in theory.
我有一个想法,但我没有尝试,但理论上可行。
Run content_script that was executed before the document was loaded, and register a ServiceWorker to replace page's requested file content in real time. (ServiceWorker can intercept all requests in the page, including those initiated directly through the dom)
运行加载文档前执行的content_script,注册一个ServiceWorker,实时替换页面请求的文件内容。(ServiceWorker可以拦截页面中的所有请求,包括直接通过dom发起的请求)
回答by Josh
It's not a Chrome extension, but Fiddler can change the script to point to your development server (see this answerfor setup instructions from the author of Fiddler). Also, with Fiddler you can setup a search and replace to add that extra parameter that you need.
它不是 Chrome 扩展程序,但 Fiddler 可以更改脚本以指向您的开发服务器(有关 Fiddler 作者的设置说明,请参阅此答案)。此外,使用 Fiddler,您可以设置搜索和替换以添加您需要的额外参数。