-1

say I have the following config.json file :

{
    "level1":{
        "level1_1":{
            "example": "test",
            "example2":"123123"
        },
        "level1_2":{
            "example": "test",
            "example2":"123123"
        }
    },

    "level2":{
        "level2_1":{
            "example": "test",
            "example2":"123123"
        },
        "level2_2":{
            "example": "test",
            "example2":"123123"
        }
    }
}

I just want to read , say the value of level2_2.example2 in a html file, looking like the following :

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>reading json</title>
  <style>

  </style>

</head>
<body>

  <br>
  <div id="output">file value : </div>
  <br>

<script>

// Starts.
init();

function loadJSON(callback) {
  var xobj = new XMLHttpRequest();
      xobj.overrideMimeType("application/json");
  xobj.open('GET', 'config.json', true); // Replace 'my_data' with the path to your file
  xobj.onreadystatechange = function () {
        if (xobj.readyState == 4 && xobj.status == "200") {
          // Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
          callback(xobj.responseText);
          // init(xobj.responseText)
        }
  };
  xobj.send(null);
}

function init() {
  loadJSON(function(response) {

    // Parse JSON string into object
    var actual_JSON = JSON.parse(response);

    // Transforms the JSON object into a readable string.
    var json_string = JSON.stringify(actual_JSON, undefined, 2);

    // Select <br> tag.
    var output = document.querySelector("#output");

    // Adds it to the DOM.
    output.innerHTML += json_string;
  });
}

</script>
</body>

Calling the HTML file directly delivers the following error :

Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, brave, https.

so I have the following nodejs script to run a server:

    var http = require('http');
var fs =require('fs');


var server = http.createServer(function(req,res){
    console.log('request was made : '+req.url);
    res.writeHead(200,{'Content-Type':'text/html'});
    var myReadStream  = fs.createReadStream(__dirname +'/index.html','utf8');
    myReadStream.pipe(res);
});

server.listen('3000','127.0.0.1');

console.log('listening to 3000');

calling the the address delivers than the following error:

 Uncaught SyntaxError: Unexpected token < in JSON at position 0
    at JSON.parse (<anonymous>)
    at (index):40
    at XMLHttpRequest.xobj.onreadystatechange ((index):29)
(anonymous) @ (index):40
xobj.onreadystatechange @ (index):29
XMLHttpRequest.send (async)
loadJSON @ (index):33
init @ (index):37
(anonymous) @ (index):20

So The question here is; what I'm missing or not understand here? and can I call a specific element in the json file ?

mingos
  • 23,778
  • 12
  • 70
  • 107
Engine
  • 5,360
  • 18
  • 84
  • 162
  • It might have to do with the _type_ of file you are passing back: `{'Content-Type':'text/html'}`. Otherwise I would strongly advice you to move away from XMLHttpRequest and simply use `fetch`, then you can do `fethc(json).then(response => response.json().then( callback ))` and not bother with the complexities youn are introducing. When it comes to local servers, I would also wanna point you to things like Express, or the one I user; BrowserSync. Then you do not have to figure out the intricacies of serving files. – somethinghere Jul 26 '19 at 08:20
  • 2
    Most likely your nodejs is not outputting what you think it is. I suggest that you do `console.log(response)` in your `loadJSON` function, to see what are you getting from node. Also, try manually to access http://..../config.json and see what you get – dkasipovic Jul 26 '19 at 08:20
  • @Damir do have an example how to do it ? – Engine Jul 26 '19 at 08:23
  • `Cross origin requests are only supported for protocol schemes: ....` probably means you are just running the html file in the browser directly with a `file://users/bob/www/index.html` try loading the html file via a server `http://` – Endless Jul 26 '19 at 08:23
  • 1
    @Endless yes and that's why I trying wiht nodesj – Engine Jul 26 '19 at 08:24
  • @Engine just do 'console.log(response)' as first line of your loadJSON function. Also consider what Endless said, maybe run local apache server, then you wont need NodeJS – dkasipovic Jul 26 '19 at 08:26
  • well that would be see it in the console not using or delivering it tothe html file ? – Engine Jul 26 '19 at 08:29
  • Or simply check your browser's developer tools (F12) , network tab, and see what your query returns. – Jeremy Thille Jul 26 '19 at 08:32
  • 1
    `calling the the address delivers the following error` : what address are you talking about? Are you calling `config.json` ? There is no such handler or route in your Node server, it doesn't know what to do with it and therefore won't magically send back the `config.json` file. If you are simply calling the `index.html` file, try to send the file directly (fs.readFile) instead of _streaming_ it – Jeremy Thille Jul 26 '19 at 08:36

2 Answers2

1

Your issue is that the HTML page is likely open via the file:// protocol and the Node server is run at http://localhost:8080 or something along these lines. The hosts are therefore not the same. Browsers will block cross-origin requests (requests made from one host to another) unless the target responds with a specific header or the hosts are identical. Bear in mind that even if both the HTML file and the API are served on the same host, but on different ports, CORS will still kick in and the request will get blocked.

In your Node app, you can add the header before sending the response:

res.header("Access-Control-Allow-Origin", "*");

This will allow all hosts (all origins) to successfully send requests to your server without the browser blocking them. In a production environment, you'll want this to contain the specific host instead of a wildcard, but for development purposes, this will allow you to work normally.

Another possibility is to serve static files from the context of your Node server so that the HTML page and the API will both reside under the same host (localhost:8080 or whatever your case is). The issue of CORS will be nonexistent then.

mingos
  • 23,778
  • 12
  • 70
  • 107
1
  function readJsonFile(file, callback) {
    var rawFile = new XMLHttpRequest();
    rawFile.overrideMimeType("application/json");
    rawFile.open("GET", file, true);
    rawFile.onreadystatechange = function() {
      if (rawFile.readyState === 4 && rawFile.status == "200") {
        callback(rawFile.responseText);
      }
    }
      rawFile.send(null);
    }

  /* usage */
  readJsonFile("http://localhost/projects-name/my_data.json", function(text){
    var data = JSON.parse(text);
    console.log(data);
  });

NOTE: Use $.get instead of function this if you are getting data from external url.

 $.getJSON("http://localhost/projects-name/my_json", function(text) {

   var PatternData = JSON.parse(JSON.stringify(text));

// 
//readJsonFile("http://localhost/project-name/json/my_data.json", function(text) {

//var PatternData = JSON.parse(text);

Link: https://github.com/gmkhussain/frontend#how-to-get-json-data-from-external-file-in-javascript

GMKHussain
  • 3,342
  • 1
  • 21
  • 19