3

I've written a small I18n plugin that accepts different languages via json. To make usage as simple as possible for the user, I want them to be able to just plop their json package directly in a page's along with the actual script:

<script id="pop-language_es" type="application/json" src='languages/es.json'></script>
<script src='pop.js'></script>

To keep this plugin as lean as possible, I want to avoid external dependencies like Jquery. I can retrieve the script tag using pure js:

var json = document.getElementById("pop-language_es");

The problem is, this is only the tag, not the actual json. Is there a way to retrieve the contents with something like json.content?

There's a similar question here, in which several people recommend using Ajax. That would definitely work in this situation, but wouldn't that result in the client downloading the json twice? (First during the page load, then again during the Ajax call.) If so, I'd hope there's a better option, as these json files can get quite large.

Community
  • 1
  • 1
nullnullnull
  • 8,039
  • 12
  • 55
  • 107
  • 2
    You can't read the contents of ` – Pointy Feb 21 '14 at 22:11
  • 1
    A JSONP-like solution might work here, where es.json is written to invoke a pre-defined function with its payload. – Gabriel Isenberg Feb 21 '14 at 22:12
  • 1
    Note: JSON files are *not* valid/useful JavaScript programs. You'll either have to use something like AJAX to access the raw data, or wrap the JSON file *contents* (making "not a JSON file") such as a JSON-P or "side-effect" solution as proposed by Gabriel or Jasper. – user2864740 Feb 21 '14 at 22:14
  • Wow! I just want to say that the JS community on Stackoverflow is incredible. I'm used to posting Ruby questions, where it might take 10-15 minutes for a response. It's only been five minutes and there are already three answers and several comments. Thanks, you all! – nullnullnull Feb 21 '14 at 22:17

2 Answers2

4

What you can do is set a global variable within your external file:

window.myJSON = { ... };

Then your other code can access that data via window.myJSON.

I'm not sure how browsers parse .json files so you may need to change the extension to .js.

Jasper
  • 75,717
  • 14
  • 151
  • 146
  • 1
    Very bad idea. Never pollute the global namespace. This is one of the bad things about JS, that you can actually access the global namespace. – Hidde Feb 21 '14 at 22:13
  • @Hidde I read that over and over, but what exactly is gonna happen if you use `window.Myvar4456Sgj_Only_exists_hERe = {}`? Someone can delete it with another script, someone can read it with another script, what real issues are created? – Jasper Feb 21 '14 at 22:14
  • 1
    It is a matter of style. Usually people give short names to variables, and a global namespace is (in my opinion) made for libraries and constants. Libraries to have a modular page, constants to be able to access them everywhere. – Hidde Feb 21 '14 at 22:17
  • I prefer using a top-level discriminator (e.g. `window.Acme.xyz`), but the *actual* issue with this approach, wrt the question, is that it won't work with plain "JSON" files, and instead requires providing a JS file (with such a modification). This also means that the user can now run arbitrary code, which likely isn't an issue but is a side-effect. – user2864740 Feb 21 '14 at 22:17
  • @user2864740 Without the ability to read the JSON file server-side or via an AJAX call, there's no way to mess with the external JSON that I can think of. Anything come to mind? – Jasper Feb 21 '14 at 22:22
  • @Jasper Nope. If I had to pick one approach that didn't use AJAX, this is the one I'd possibly choose as it will work (which is why I duly upvoted it) .. but it does come with some caveats. – user2864740 Feb 21 '14 at 22:22
  • Converting to a JS standard is still an option at this stage, and will probably make things easier all around. This seems like the best approach. – nullnullnull Feb 21 '14 at 22:23
  • 1
    @timothythehuman If you're just starting to define the format, I'd recommend following one of the various "AMD module patterns". Then you can either inject your own `define` handler (e.g. and then handle the result of the module definition directly) or rely on something like RequireJS to fetch the content. – user2864740 Feb 21 '14 at 22:24
  • 1
    I hadn't considered using RequireJS for loading the language modules. We're actually using Require in development, but slim it down with almond for production. If we just keep the full library, then users can require whatever modules they want, which would actually be much simpler than the current approach. Yeah, I like that a lot! – nullnullnull Feb 21 '14 at 22:31
0

Once you include your javascript file, you are able to access it's content (variable,methods,...) within your main file. document.getElementById has nothing to do with the contents on it, it is only looking for the DOM element itself, not the file.

htatche
  • 693
  • 3
  • 17