12

For development purposes, I'd like to be able to easily load locally-stored scripts into the browser instead of having to copy-paste to the console.

Creating a new <script> element isn't working, it gives a Not allowed to load local resource: file://.... error (in Chrome).

Also, creating a userscript won't work--I'd have to re-install it every time I make an edit.

Is there an alternative way to easily load a local script via a bookmarklet/etc?

Manishearth
  • 14,882
  • 8
  • 59
  • 76
  • 1
    If we're allowed to branch outside of JavaScript and the browser, here, maybe serve your script on a local server (perhaps you're doing local development)? You can start a local server with one line of Python. – cheeken May 16 '12 at 04:01
  • @cheeken: Yeah, that's actually a good idea.. I _do_ have Apache installed, and I anyway do my development in the Apache folder, so that's a great alternative! – Manishearth May 16 '12 at 05:34

5 Answers5

26

In Chrome, you can create an extension that holds all of the local files that you need to load. It will make your files accessible via chrome-extension://... instead of file://...

Make a file named manifest.json in a new folder and fill it with:

{
  "name": "File holder",
  "manifest_version": 2,
  "version": "1.0",
  "web_accessible_resources": ["test.js", "other.js", "yetanother.js"]
}

Then, put all the scripts you want to load in that new directory, and make sure they are included in the web_accessbile_reources manifest list. Load the extension by going to chrome://extensions, enabling Developer Mode, and selecting the new folder with Load unpacked extension....

Now you can access all the files in your extension directory using chrome-extension://[app_id]/[file_name], where "app_id" is the hash listed for the extension on the chrome://extensions page. Note that because the protocols and hostnames differ from where you've doing your actual work (unless you decide to do all your development in the extension folder, which might be acceptable to you), the extension resources are cross-domain and can only be loaded via <script> tag.

Now from the console, you can do:

var s = document.createElement("script");
s.src = "chrome-extension://aefigdoelbemgaedgkcjpcnilbgagpcn/test.js";
document.body.appendChild(s);

(Assuming your file is test.js and your app id is aefigdoelbemgaedgkcjpcnilbgagpcn.)

It's a quite bit to type, I know, but perhaps you can store the chrome-extension://[app_id] part as a shorthand variable?

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • I tried doing this with Chrome 22, and it displayed a warning that manifest version 1 support is being phased out. The documentation on changes in v2 includes "A package's resources are no longer available by default to external websites (as the src of an image, or a script tag). If you want a website to be able to load a resource contained in your package, you'll need to explicitly whitelist it via the web_accessible_resources manifest attribute. This is particularly relevant for extensions that build up an interface on a website via injected content scripts." I suspect we'll need this. – Barmar Sep 25 '12 at 16:41
  • Once I load the script file, how do I use it? My .js file contains a single top-level function definition, but when I try to call it in the Javascript console it says it's not defined. – Barmar Sep 25 '12 at 17:03
  • @Barmar: This answer was written before manifest version 2 was in widespread use. Thanks for the notice; I'll correct it now. – apsillers Sep 25 '12 at 19:43
  • @Barmar: The load happens asynchronously. If you trying to use the function *immediately* after you append the `script` tag, your function call will fail, because the script hasn't loaded yet. Instead, you need to use an `onload` handler to run after the script loads. I made a fiddle to demonstrate: http://jsfiddle.net/GvS2B/2/ – apsillers Sep 25 '12 at 19:54
  • I'm just typing the statements in your answer in the JavaScript console, not putting them in a web page. I just want some utility functions that I can use by hand when debugging. – Barmar Sep 25 '12 at 19:59
  • @Barmar You should 1) append the tag by running my three-line injection above, 2) wait a second or two after running that code on the console, and *then* 3) try to use the function as a *separate command* on the console. If that doesn't work, then I there is probably something wrong with your script or your extension setup, and you should open a separate question to address that problem. – apsillers Sep 25 '12 at 20:05
2

Sadly, Chrome doesn't allow you to load local files via AJAX; however, you can work around this limitation by launching the browser with the flag --disable-web-security (details vary per host operating system).

maerics
  • 151,642
  • 46
  • 269
  • 291
  • 5
    Might I suggest `--allow-file-access-from-files` instead? That will allow all other Web security feature to stay in effect and (I believe) still achieve the desired result. – apsillers May 16 '12 at 05:14
  • Interesting find but [this SO answer](http://stackoverflow.com/a/4271569/244128) raises some concerns about the effectiveness of that feature based on its [outstanding issues](http://code.google.com/p/chromium/issues/detail?id=4197&can=1&q=allow-file-access-from-files&colspec=ID%20Stars%20Pri%20Area%20Feature%20Type%20Status%20Summary%20Modified%20Owner%20Mstone%20OS). – maerics May 16 '12 at 05:29
1

run chrome as: chrome.exe --allow-file-access-from-files from CLI

mostafa amiri
  • 118
  • 1
  • 6
0

you need to run local http server

this is a good document for this:

https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server

mostafa amiri
  • 118
  • 1
  • 6
-1

Have you tried a relative path from your page to your js file liek so...

src='/js/javascript.js'

Sunil Dodiya
  • 2,605
  • 2
  • 18
  • 21