491

I'm trying to load a local JSON file but it won't work. Here is my JavaScript code (using jQuery):

var json = $.getJSON("test.json"); var data = eval("(" +json.responseText + ")"); document.write(data["a"]); 

The test.json file:

{"a" : "b", "c" : "d"} 

Nothing is displayed and Firebug tells me that data is undefined. In Firebug I can see json.responseText and it is good and valid, but it's strange when I copy the line:

 var data = eval("(" +json.responseText + ")"); 

in Firebug's console, it works and I can access data.

Does anyone have a solution?

4
  • 2
    When you return a JSON string you're already retrieving a javascript object, no need to use eval(). Commented Sep 8, 2011 at 10:29
  • 4
    What do you call a "local" json file? local on the browser or the server? Commented Sep 8, 2011 at 10:31
  • 7
    You haven't given us enough details. The file test.json doesn't specify any path so it is therefore a relative URI, relative to the location of the page accessing it. So like @seppo0010 says it will be local to the server if the page is on a remote server somewhere and it will be relative to your computer if the page is in your local filesystem accessed by the file:// protocol. Commented Oct 23, 2012 at 7:41
  • @seppo0010 Its local to my disk in the same folder. I am loading local file for first time, don't know why loading url is easier as I thought I had to do same. i.e. load JSON file from relative path Commented Jan 12, 2021 at 10:36

26 Answers 26

356

$.getJSON is asynchronous so you should do:

$.getJSON("test.json", function(json) { console.log(json); // this will show the info it in firebug console }); 
Sign up to request clarification or add additional context in comments.

11 Comments

Are you really allowed to access a local file?
No, it cannot be file but must be served by web server.
Absolutely correct. Chromes security is much tighter than Firefox or others. Loading anything using xhr, Josn, Xml etc is pretty much all locked down in Chrome with the exception of one or two things.
I tried this, but no luck. No error in console as well :(
Chrome allows you to access local JSON or other data files if you launch it with the --allow-file-access-from-files flag. I checked this with the code above on version 34.0.1847.131 m; it should work on other versions as well.
|
254

I had the same need (to test my angularjs app), and the only way I found is to use require.js:

var json = require('./data.json'); //(with path) 

note: the file is loaded once, further calls will use the cache.

More on reading files with nodejs: http://docs.nodejitsu.com/articles/file-system/how-to-read-files-in-nodejs

require.js: http://requirejs.org/

6 Comments

If you're doing this with jest, then remember to do jest.dontMock('./data.json'); or else the result is empty. Might be useful for someone out there :)
What is the context of this code? What do you do with json?
Kindly provide full example : I am getting error : has not been loaded yet for context: _. Use require([])
require is not working on browser because it's node.js module. if OP wants to load it in browser, should use fetch is the right solution.
Yes, require is for node, but requireJS can be used in browsers too: "RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node."
|
197

In a more modern way, you can now use the Fetch API:

fetch("test.json") .then(response => response.json()) .then(json => console.log(json)); 

All modern browsers support Fetch API. (Internet Explorer doesn't, but Edge does!)

or with async/await

async function printJSON() { const response = await fetch("test.json"); const json = await response.json(); console.log(json); } 

source:

7 Comments

When using the Fetch API, are you still forbidden to access local files, unless you disable a security setting?
@LarsH Apparently yes, I tried it this morning and fetch api is unable to read a local json file with file:// scheme. This approach looks so clean but you can't use it for local files
@keysl OK, I guess it probably has to be that way for security reasons. (And you're right, I meant "forbidden to access files via the file:// scheme.) But it is a nice clean approach. I've started using it thanks to this answer.
You cannot access local files with fetch API
Only HTTP(S) protocols are supported by fetch!
|
126

If you want to let the user select the local json file (anywhere on the filesystem), then the following solution works.

It uses FileReader and JSON.parser (and no jquery).

<html> <body> <form id="jsonFile" name="jsonFile" enctype="multipart/form-data" method="post"> <fieldset> <h2>Json File</h2> <input type='file' id='fileinput'> <input type='button' id='btnLoad' value='Load' onclick='loadFile();'> </fieldset> </form> <script type="text/javascript"> function loadFile() { var input, file, fr; if (typeof window.FileReader !== 'function') { alert("The file API isn't supported on this browser yet."); return; } input = document.getElementById('fileinput'); if (!input) { alert("Um, couldn't find the fileinput element."); } else if (!input.files) { alert("This browser doesn't seem to support the `files` property of file inputs."); } else if (!input.files[0]) { alert("Please select a file before clicking 'Load'"); } else { file = input.files[0]; fr = new FileReader(); fr.onload = receivedText; fr.readAsText(file); } function receivedText(e) { let lines = e.target.result; var newArr = JSON.parse(lines); } } </script> </body> </html> 

Here is a good intro on FileReader: http://www.html5rocks.com/en/tutorials/file/dndfiles/

3 Comments

The FileReader API is not supported in IE 8 or 9, but all other browsers are OK: caniuse.com/#search=filereader
It works perfect in Chrome, you will see your data in newArr
This answer is nice and a little different because its not using jQuery.
118

If you're looking for something simple, just load the data in the head of your HTML:

data.js

var DATA = {"a" : "b", "c" : "d"}; 

index.html

<head> <script src="data.js" ></script> <script src="main.js" ></script> </head> 

main.js

(function(){ console.log(DATA); // {"a" : "b", "c" : "d"} })(); 

However, if your data is larger than your heap size, try another browser. To check the size do:

window.performance.memory.jsHeapSizeLimit / 1024 / 1024 / 1024 + " GBs" // "4.046875 GBs" 

Update ES6:

Instead of using the <script> tag to load your data, you can load it directly inside your main.js using import assert

import data from './data.json' assert {type: 'json'}; 

9 Comments

you are right that AMD would work but I do no think AMD is the right solution here. the simplest is to use $.getJSON. thanks
@PatrickBrowne yes, getJSON is a good solution but I think in many cases you're going to run into an cross-domain issue (loading the data from S3 for instance).
This is wrong in many levels, I don't understand how it has so many votes, here it explains more if anyone wants to see codepen.io/KryptoniteDove/post/… "Many examples will evidence that you can access the data with a simple function such as the one below. In fact, what this is not actually loading a JSON document but creating a Javascript object. This technique will not work for true JSON files."
honestly this is a great solution if you just have some pre-canned data and u want to serve a static page
@lesolorzanov - the browser is still going to block it because of the same origin policy.
|
33

how to using XMLHttpRequest to load the local json file

ES5 version

// required use of an anonymous callback, // as .open() will NOT return a value but simply returns undefined in asynchronous mode! function loadJSON(callback) { var xObj = new XMLHttpRequest(); xObj.overrideMimeType("application/json"); xObj.open('GET', './data.json', true); // 1. replace './data.json' with the local path of your file xObj.onreadystatechange = function() { if (xObj.readyState === 4 && xObj.status === 200) { // 2. call your callback function callback(xObj.responseText); } }; xObj.send(null); } function init() { loadJSON(function(response) { // 3. parse JSON string into JSON Object console.log('response =', response); var json = JSON.parse(response); console.log('your local JSON =', JSON.stringify(json, null, 4)); // 4. render to your page const app = document.querySelector('#app'); app.innerHTML = '<pre>' + JSON.stringify(json, null, 4) + '</pre>'; }); } init();
<section id="app"> loading... </section>

ES6 version

// required use of an anonymous callback, // as .open() will NOT return a value but simply returns undefined in asynchronous mode! const loadJSON = (callback) => { const xObj = new XMLHttpRequest(); xObj.overrideMimeType("application/json"); // 1. replace './data.json' with the local path of your file xObj.open('GET', './data.json', true); xObj.onreadystatechange = () => { if (xObj.readyState === 4 && xObj.status === 200) { // 2. call your callback function callback(xObj.responseText); } }; xObj.send(null); } const init = () => { loadJSON((response) => { // 3. parse JSON string into JSON Object console.log('response =', response); const json = JSON.parse(response); console.log('your local JSON =', JSON.stringify(json, null, 4)); // 4. render to your page const app = document.querySelector('#app'); app.innerHTML = `<pre>${JSON.stringify(json, null, 4)}</pre>`; }); } init();
<section id="app"> loading... </section>

online demo

https://cdn.xgqfrms.xyz/ajax/XMLHttpRequest/index.html

11 Comments

@Pier if you use a local application Server like Tomcat or Xampp or Jboss . the script work
@MirkoCianfarani indeed because you are not using the file:/// protocol and the file cannot considered local anymore.
//xobj.status is integer xobj.status === "200" should be xobj.status === 200
The question says explicitely "local file", so not through HTTP.
@xgqfrms An online demo will not reproduce what happens with file:// URLs.
|
17

Add to your JSON file from the beginning

var object1 = [ 

and at the end

] 

Save it

Then load it with pure js as

<script type="text/javascript" src="1.json"></script> 

And now you can use it as object1 - its already loaded!

Works perfectly in Chrome and without any additional libraries

3 Comments

but better rename it to 1.js
But is it still json if you turn it into js?
Well it's definitely not json if you put javascript variable declarations in front of it...
13

I can't believe how many times this question has been answered without understanding and/or addressing the problem with the Original Poster's actual code. That said, I'm a beginner myself (only 2 months of coding). My code does work perfectly, but feel free to suggest any changes to it. Here's the solution:

//include the 'async':false parameter or the object data won't get captured when loading var json = $.getJSON({'url': "http://spoonertuner.com/projects/test/test.json", 'async': false}); //The next line of code will filter out all the unwanted data from the object. json = JSON.parse(json.responseText); //You can now access the json variable's object data like this json.a and json.c document.write(json.a); console.log(json); 

Here's a shorter way of writing the same code I provided above:

var json = JSON.parse($.getJSON({'url': "http://spoonertuner.com/projects/test/test.json", 'async': false}).responseText); 

You can also use $.ajax instead of $.getJSON to write the code exactly the same way:

var json = JSON.parse($.ajax({'url': "http://spoonertuner.com/projects/test/test.json", 'async': false}).responseText); 

Finally, the last way to do this is to wrap $.ajax in a function. I can't take credit for this one, but I did modify it a bit. I tested it and it works and produces the same results as my code above. I found this solution here --> load json into variable

var json = function () { var jsonTemp = null; $.ajax({ 'async': false, 'url': "http://spoonertuner.com/projects/test/test.json", 'success': function (data) { jsonTemp = data; } }); return jsonTemp; }(); document.write(json.a); console.log(json); 

The test.json file you see in my code above is hosted on my server and contains the same json data object that he (the original poster) had posted.

{ "a" : "b", "c" : "d" } 

2 Comments

You didn't understand either what "local file" means in the question: not HTTP.
It works like a charm and the explanation is also correct!
12

I'm surprised import from es6 has not been mentioned (use with small files)

Ex: import test from './test.json'

webpack 2< uses the json-loader as default for .json files.

https://webpack.js.org/guides/migrating/#json-loader-is-not-required-anymore

For TypeScript:

import test from 'json-loader!./test.json'; 

TS2307 (TS) Cannot find module 'json-loader!./suburbs.json'

To get it working I had to declare the module first. I hope this will save a few hours for someone.

declare module "json-loader!*" { let json: any; export default json; } ... import test from 'json-loader!./test.json'; 

If I tried to omit loader from json-loader I got the following error from webpack:

BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders. You need to specify 'json-loader' instead of 'json', see https://webpack.js.org/guides/migrating/#automatic-loader-module-name-extension-removed

2 Comments

easy and straightforward.
You cannot use the es6 import statement when the webpage is loaded with the file: protocol.
7

Recently D3js is able to handle local json file.

This is the issue https://github.com/mbostock/d3/issues/673

This is the patch inorder for D3 to work with local json files. https://github.com/mbostock/d3/pull/632

1 Comment

this answer would be much improved with an example of how to use D3 to read json files.
7

What I did was editing the JSON file little bit.

myfile.json => myfile.js

In the JSON file, (make it a JS variable)

{name: "Whatever"} => var x = {name: "Whatever"}

At the end,

export default x;

Then,

import JsonObj from './myfile.js';

Comments

6

Found this thread when trying (unsuccessfully) to load a local json file. This solution worked for me...

function load_json(src) { var head = document.getElementsByTagName('head')[0]; //use class, as we can't reference by id var element = head.getElementsByClassName("json")[0]; try { element.parentNode.removeChild(element); } catch (e) { // } var script = document.createElement('script'); script.type = 'text/javascript'; script.src = src; script.className = "json"; script.async = false; head.appendChild(script); //call the postload function after a slight delay to allow the json to load window.setTimeout(postloadfunction, 100) } 

... and is used like this...

load_json("test2.html.js") 

...and this is the <head>...

<head> <script type="text/javascript" src="test.html.js" class="json"></script> </head> 

5 Comments

This does not seem very reusable. For example, if the json file is served by a remote server, 100ms timeout may not be enough for load. And as the time depends on the client's connection speed, you would have to set a very long timeout for clients with slow connection. In short, setTimeout should not be used to wait for loading of a resource.
Kenny806 - It's meant to solve a specific problem - loading local resources (for a non-hosted web page), so that does mean it's not very reusable. There are 1000's of resource loading solutions for web-hosted pages. This is not the solution, it's a solution. It's really simple to change the timeout. By removing the timeout, are you suggesting that an infinite wait is acceptable?
I'm not suggesting an infinite wait, I'm suggesting using a technique that allows you to react to file load as soon as it is finished. My problem with timeout is, that you always have to wait for it to finish. Even if the file would have loaded in 10ms, you would still wait for 100ms. And yes, adjusting timeout is easy, but what you are suggesting is changing the code each time you want to load a different file or when the file siize changes (to optimize the wait). Such a solution is IMHO wrong and can cause a lot of headaches in the future, especially when someone else tries to use it.
Anyone using this script should use it as a basis for their own scripts. You're entitled to your opinion on whether this script is wrong. Why not suggest an alternative solution? This definitely won't work for all use cases. It worked for me, loading a local file from a local html page. I shared my solution on this question, in the hope it would help someone else. Are you trying to load a local resource? Why not pass in the timeout value as a variable, based on the file you're loading? Ajax on local files is pretty limited.
You may be better off using onreadystatechange or onload and giving them a function. script.onload = functionname;
5

In TypeScript you can use import to load local JSON files. For example loading a font.json:

import * as fontJson from '../../public/fonts/font_name.json'; 

This requires a tsconfig flag --resolveJsonModule:

// tsconfig.json { "compilerOptions": { "module": "commonjs", "resolveJsonModule": true, "esModuleInterop": true } } 

For more information see the release notes of typescript: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html

2 Comments

May write with more details because the answer is a bit unclearly understandable.
This requires transpiling TypeScript to JavaScript. Not the easy solution you need for a quick HTML where you want to directly load a local JSON file ("local file" is mentionned in the question).
3

An approach I like to use is to pad/wrap the json with an object literal, and then save the file with a .jsonp file extension. This method also leaves your original json file (test.json) unaltered, as you will be working with the new jsonp file (test.jsonp) instead. The name on the wrapper can be anything, but it does need to be the same name as the callback function you use to process the jsonp. I'll use your test.json posted as an example to show the jsonp wrapper addition for the 'test.jsonp' file.

json_callback({"a" : "b", "c" : "d"}); 

Next, create a reusable variable with global scope in your script to hold the returned JSON. This will make the returned JSON data available to all other functions in your script instead of just the callback function.

var myJSON; 

Next comes a simple function to retrieve your json by script injection. Note that we can not use jQuery here to append the script to the document head, as IE does not support the jQuery .append method. The jQuery method commented out in the code below will work on other browsers that do support the .append method. It is included as a reference to show the difference.

function getLocalJSON(json_url){ var json_script = document.createElement('script'); json_script.type = 'text/javascript'; json_script.src = json_url; json_script.id = 'json_script'; document.getElementsByTagName('head')[0].appendChild(json_script); // $('head')[0].append(json_script); DOES NOT WORK in IE (.append method not supported) } 

Next is a short and simple callback function (with the same name as the jsonp wrapper) to get the json results data into the global variable.

function json_callback(response){ myJSON = response; // Clone response JSON to myJSON object $('#json_script').remove(); // Remove json_script from the document } 

The json data can now be accessed by any functions of the script using dot notation. As an example:

console.log(myJSON.a); // Outputs 'b' to console console.log(myJSON.c); // Outputs 'd' to console 

This method may be a bit different from what you are used to seeing, but has many advantages. First, the same jsonp file can be loaded locally or from a server using the same functions. As a bonus, jsonp is already in a cross-domain friendly format and can also be easily used with REST type API's.

Granted, there are no error handling functions, but why would you need one? If you are unable to get the json data using this method, then you can pretty much bet you have some problems within the json itself, and I would check it on a good JSON validator.

1 Comment

I'm missing how you link things together. When and how do you call getLocalJSON and json_callback?
2

In angular (or any other framework), you can load using http get I use it something like this:

this.http.get(<path_to_your_json_file)) .success((data) => console.log(data)); 

Hope this helps.

1 Comment

The question is about a file:// loading context.
2

You can put your json in a javascript file. This can be loaded locally (even in Chrome) using jQuery's getScript() function.

map-01.js file:

var json = '{"layers":6, "worldWidth":500, "worldHeight":400}' 

main.js

$.getScript('map-01.js') .done(function (script, textStatus) { var map = JSON.parse(json); //json is declared in the js file console.log("world width: " + map.worldWidth); drawMap(map); }) .fail(function (jqxhr, settings, exception) { console.log("error loading map: " + exception); }); 

output:

world width: 500 

Notice that the json variable is declared and assigned in the js file.

Comments

1
$.ajax({ url: "Scripts/testingJSON.json", //force to handle it as text dataType: "text", success: function (dataTest) { //data downloaded so we call parseJSON function //and pass downloaded data var json = $.parseJSON(dataTest); //now json variable contains data in json format //let's display a few items $.each(json, function (i, jsonObjectList) { for (var index = 0; index < jsonObjectList.listValue_.length;index++) { alert(jsonObjectList.listKey_[index][0] + " -- " + jsonObjectList.listValue_[index].description_); } }); } }); 

1 Comment

This is a different piece of code when compared with other answers. Tested and found this does not work for file:/// protocol.
1

If you are using a local array for JSON - as you showed in your example in the question (test.json) then you can is the parseJSON() method of JQuery ->

var obj = jQuery.parseJSON('{"name":"John"}'); alert( obj.name === "John" ); 

getJSON() is used for getting JSON from a remote site - it will not work locally (unless you are using a local HTTP Server)

3 Comments

Yes, but how do you load a local JSON file? This doesn't really answer the question.
@Stefan read the bottom sentence - you cant
this is exactly the opposite of the required answer
0

How I was able to load the data from a json file in to a JavaScript variable using simple JavaScript:

let mydata; fetch('datafile.json') .then(response => response.json()) .then(jsonResponse => mydata = jsonResponse) 

Posting here as I didn't find this kind of "solution" I was looking for.

Note: I am using a local server run via the usual "python -m http.server" command.

Comments

0

$.getJSON only worked for me in Chrome 105.0.5195.125 using await, which works a script type of module.

<script type="module"> const myObject = await $.getJSON('./myObject.json'); console.log('myObject: ' + myObject); </script> 

Without await, I see:

Uncaught TypeError: myObject is not iterable 

when resolving myObject.

Without type="module" I see:

Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules 

Comments

-1

I haven't found any solution using Google's Closure library. So just to complete the list for future vistors, here's how you load a JSON from local file with Closure library:

goog.net.XhrIo.send('../appData.json', function(evt) { var xhr = evt.target; var obj = xhr.getResponseJson(); //JSON parsed as Javascript object console.log(obj); }); 

Comments

-1

json_str = String.raw`[{"name": "Jeeva"}, {"name": "Kumar"}]`; obj = JSON.parse(json_str); console.log(obj[0]["name"]);

I did this for my cordova app, like I created a new javascript file for the JSON and pasted the JSON data into String.raw then parse it with JSON.parse

3 Comments

If it's a javascript file why do an object so and not simply using JavaScript Object Notation (JSON): obj = [{"name": "Jeeva"}, {"name": "Kumar"}]
I used it beause I fetched some json data using ajax, which came as string, so I use JSON.parse to convert to an JavaScript object
Embedding the JSON data in the script is not the question asked.
-1
function readTextFile(srcfile) { try { //this is for IE var fso = new ActiveXObject("Scripting.FileSystemObject");; if (fso.FileExists(srcfile)) { var fileReader = fso.OpenTextFile(srcfile, 1); var line = fileReader.ReadLine(); var jsonOutput = JSON.parse(line); } } catch (e) { } } readTextFile("C:\\Users\\someuser\\json.txt"); 

What I did was, first of all, from network tab, record the network traffic for the service, and from response body, copy and save the json object in a local file. Then call the function with the local file name, you should be able to see the json object in jsonOutout above.

2 Comments

Please explain your solution instead of just pasting the code. Only a solution explaining how it solved the problem will help the community.
Note: Requires InternetExplorer
-1

What worked for me is the following:

Input:

http://ip_address//some_folder_name//render_output.html?relative/path/to/json/fie.json 

Javascript Code:

<html> <head> <style> pre {} .string { color: green; } .number { color: darkorange; } .boolean { color: blue; } .null { color: magenta; } .key { color: red; } </style> <script> function output(inp) { document.body.appendChild(document.createElement('pre')).innerHTML = inp; } function gethtmlcontents(){ path = window.location.search.substr(1) var rawFile = new XMLHttpRequest(); var my_file = rawFile.open("GET", path, true) // Synchronous File Read //alert('Starting to read text') rawFile.onreadystatechange = function () { //alert("I am here"); if(rawFile.readyState === 4) { if(rawFile.status === 200 || rawFile.status == 0) { var allText = rawFile.responseText; //alert(allText) var json_format = JSON.stringify(JSON.parse(allText), null, 8) //output(json_format) output(syntaxHighlight(json_format)); } } } rawFile.send(null); } function syntaxHighlight(json) { json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { var cls = 'number'; if (/^"/.test(match)) { if (/:$/.test(match)) { cls = 'key'; } else { cls = 'string'; } } else if (/true|false/.test(match)) { cls = 'boolean'; } else if (/null/.test(match)) { cls = 'null'; } return '<span class="' + cls + '">' + match + '</span>'; }); } gethtmlcontents(); </script> </head> <body> </body> </html> 

1 Comment

The question is about a file:// loading context.
-1

simplest way: save json file as *.js and include to html template as script.

js file like this:

let fileJsonData = { someField: someValue, ... } 

include like this:

... <script src="./js/jsonData.js"></script> ... 

After include you can call to fileJsonData in global scope.

Comments

-6

If you have Python installed on your local machine (or you don't mind install one), here is a browser-independent workaround for local JSON file access problem that I use:

Transform the JSON file into a JavaScript by creating a function that returns the data as JavaScript object. Then you can load it with <script> tag and call the function to get the data you want.

Here comes the Python code

import json def json2js(jsonfilepath, functionname='getData'): """function converting json file to javascript file: json_data -> json_data.js :param jsonfilepath: path to json file :param functionname: name of javascript function which will return the data :return None """ # load json data with open(jsonfilepath,'r') as jsonfile: data = json.load(jsonfile) # write transformed javascript file with open(jsonfilepath+'.js', 'w') as jsfile: jsfile.write('function '+functionname+'(){return ') jsfile.write(json.dumps(data)) jsfile.write(';}') if __name__ == '__main__': from sys import argv l = len(argv) if l == 2: json2js(argv[1]) elif l == 3: json2js(argv[1], argv[2]) else: raise ValueError('Usage: python pathTo/json2js.py jsonfilepath [jsfunctionname]') 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.