Załaduj lokalny plik JSON do zmiennej

113

Próbuję załadować plik .json do zmiennej w javascript, ale nie mogę go uruchomić. To prawdopodobnie tylko drobny błąd, ale nie mogę go znaleźć.

Wszystko działa dobrze, gdy używam takich danych statycznych:

var json = {
  id: "whatever",
  name: "start",
  children: [{
      "id": "0.9685",
      "name": " contents:queue"
    }, {
      "id": "0.79281",
      "name": " contents:mqq_error"
    }
  }]
}

Umieściłem wszystko, co znajduje się {}w content.jsonpliku, i próbowałem załadować to do lokalnej zmiennej JavaScript, jak wyjaśniono tutaj: załaduj json do zmiennej .

var json = (function() {
  var json = null;
  $.ajax({
    'async': false,
    'global': false,
    'url': "/content.json",
    'dataType': "json",
    'success': function(data) {
      json = data;
    }
  });
  return json;
})();

Uruchomiłem go z debugerem Chrome i zawsze mówi mi, że wartość zmiennej jsonto null. Plikcontent.json rezyduje plik w tym samym katalogu co plik .js że nazywa go.

Co mnie ominęło?

PogoMips
źródło
1
Adres URL Twojego pliku /content.jsonoznacza, że ​​plik znajduje się na poziomie głównym aplikacji internetowej. Zmień na content.json(bez ukośnika), aby wskazać ten sam katalog, w którym znajduje się plik skryptu. Tylko w przypadku, gdy plik skryptu znajduje się w katalogu głównym, zadziała.
Samich
plik znajduje się w WebContent \ jit \ content.json .. Próbowałem „url”: „/WebContent/jit/content.json”, ale zmienna nadal ma wartość null
PogoMips

Odpowiedzi:

38

Jeśli wkleiłeś obiekt content.jsonbezpośrednio do , jest to nieprawidłowy JSON. Klucze i wartości JSON muszą być umieszczone w podwójnych cudzysłowach ( "nie '), chyba że wartość jest liczbowa, logiczna nulllub złożona (tablica lub obiekt). JSON nie może zawierać funkcji ani undefinedwartości. Poniżej znajduje się Twój obiekt w prawidłowym formacie JSON.

{
  "id": "whatever",
  "name": "start",
  "children": [
    {
      "id": "0.9685",
      "name": " contents:queue"
    },
    {
      "id": "0.79281",
      "name": " contents:mqq_error"
    }
  ]
}

Miałeś też dodatkowy }.

Kevin B.
źródło
1
Nie mogę uwierzyć, że to naprawiło… dlaczego miałoby działać bezpośrednio osadzone w pliku .js bez podwójnych cudzysłowów, ale nie w pliku .json? To nie ma żadnego sensu ...
PogoMips
16
@ user1695165 - json i obiekt javascript to dwie różne rzeczy, po prostu wyglądają tak samo.
adeneo
2
@Kevin B "... chyba że wartość jest numeryczna [lub logiczna]."
Jacob Beauchamp
1
Wskazówka: możesz użyć walidatora json, takiego jak jsonlint.com , aby sprawdzić dane json przed ich użyciem.
Marco Panichi
129

Moje rozwiązanie, jak odpowiedział tutaj jest do wykorzystania:

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

Plik jest ładowany tylko raz, kolejne żądania wykorzystują pamięć podręczną.

edytuj Aby uniknąć buforowania, oto funkcja pomocnicza z tego posta podana w komentarzach za pomocą fsmodułu:

var readJson = (path, cb) => {
  fs.readFile(require.resolve(path), (err, data) => {
    if (err)
      cb(err)
    else
      cb(null, JSON.parse(data))
  })
}
Ehvince
źródło
48
Chciałem tylko określić, że to rozwiązanie wymaga dodatkowej biblioteki o nazwie RequireJS .
Luis Kabongo
4
Jak uniknąć buforowania?
nono
2
Niezalecane według Guilherme Oenning goenning.net/2016/04/14/stop-reading-json-files-with-require
Sangimed
2
TLDR; buforowanie uderzyło go w testach jednostkowych, więc udostępnia funkcję pomocniczą, aby uniknąć buforowania (ping @nono).
Ehvince
@Ehvince Oh, nie zauważyłem tego, ponieważ nie przeczytałem całego artykułu. Dzięki :-)
Sangimed
50

W przypadku ES6 / ES2015 możesz importować bezpośrednio, jak:

// example.json
{
    "name": "testing"
}


// ES6/ES2015
// app.js
import * as data from './example.json';
const {name} = data;
console.log(name); // output 'testing'

Jeśli używasz Typescript, możesz zadeklarować moduł json taki jak:

// tying.d.ts
declare module "*.json" {
    const value: any;
    export default value;
}

Od wersji 2.9 i wersji Typescript można dodawać --olveJsonModule compilerOptions wtsconfig.json

{
  "compilerOptions": {
    "target": "es5",
     ...
    "resolveJsonModule": true,
     ...
  },
  ...
}
Little Roys
źródło
5
import nie działa w Chrome v72 - nadalUncaught SyntaxError: Unexpected token *
1000 Gbps
2
Kiedy tego używam, wydaje mi się, że datajest to moduł, ale data.defaultjest to obiekt
Dustin Michels
1
Próbowałem uruchomić to w konsoli, ale bez powodzenia. Nie działa to z węzłem 12.4.0, z węzłem babel 6.26.0. Zawsze dostajęSyntaxError: Unexpected token *
mario199
2
dla ES6 / ES2015 możesz importować bezpośrednio: Wygląda na to, że podczas robienia otrzymuję błąd konsoli z import * as data from './example.json'powodu błędu typu MIME.
Fallenreaper,
jeśli używam, import * as data from './example.json';to datajest tylko modułem, ale data.defaultjest obiektem. Ale gdy używam import data from './example.json';następnie datajest przedmiotem, który jest bardziej applicapable
Nel
4

Istnieją dwa możliwe problemy:

  1. AJAX jest asynchroniczny, więc jsonbędzie niezdefiniowany po powrocie z funkcji zewnętrznej. Po załadowaniu pliku zostanie ustawiona funkcja wywołania zwrotnegojson jakąś wartość, ale w tym czasie nikogo to już nie obchodzi.

    Widzę, że próbowałeś to naprawić 'async': false. Aby sprawdzić, czy to działa, dodaj tę linię do kodu i sprawdź konsolę przeglądarki:

    console.log(['json', json]);
  2. Ścieżka może być zła. Użyj tej samej ścieżki, której użyłeś do załadowania skryptu w dokumencie HTML. Więc jeśli twój skrypt to js/script.js, użyjjs/content.json

    Niektóre przeglądarki mogą pokazać, do których adresów URL próbowały uzyskać dostęp i jak poszło (kody powodzenia / błędu, nagłówki HTML itp.). Sprawdź narzędzia programistyczne przeglądarki, aby zobaczyć, co się dzieje.

Aaron Digulla
źródło
Może jego wersja jquery jeszcze tego nie obsługuje? Poprawiłem sformułowanie.
Aaron Digulla
4

Wbudowany moduł node.js fs zrobi to asynchronicznie lub synchronicznie, w zależności od Twoich potrzeb.

Możesz go załadować za pomocą var fs = require('fs');

Asynchroniczny

fs.readFile('./content.json', (err, data) => {
    if (err)
      console.log(err);
    else {
      var json = JSON.parse(data);
    //your code using json object
    }
})

Synchroniczny

var json = JSON.parse(fs.readFileSync('./content.json').toString());
Arnaud M.
źródło
-1

Dla podanego formatu json, jak w pliku ~ / my-app / src / db / abc.json:

  [
      {
        "name":"Ankit",
        "id":1
      },
      {
        "name":"Aditi",
        "id":2
      },
      {
        "name":"Avani",
        "id":3
      }
  ]

w celu zaimportowania do pliku .js, takiego jak ~ / my-app / src / app.js:

 const json = require("./db/abc.json");

 class Arena extends React.Component{
   render(){
     return(
       json.map((user)=>
        {
          return(
            <div>{user.name}</div>
          )
        }
       )
      }
    );
   }
 }

 export default Arena;

Wynik:

Ankit Aditi Avani
Ank_247shbm
źródło
To jest odpowiedź na pytanie, które nie zostało tutaj zadane.
Kevin B
@KevinB zgodnie z moim wyjaśnieniem zaimportowałem plik .json do pliku .js. Pomogło mi to załadować plik json do const json. Stąd mogę użyć następującego słownika json dla atrybutów użytkownika i tak dalej.
Ank_247shbm
To świetnie, jednak to pytanie dotyczy użytkownika próbującego skopiować literał obiektu do pliku .json, który następnie ładuje za pomocą ajax, tylko ich literał obiektu był w formacie, który nie był prawidłowy dla JSON. Podczas gdy instalacja reaguje i importowanie tego z wymaganiem z pewnością działałoby w niektórych przypadkach, tak naprawdę nie pomaga w tym przypadku.
Kevin B
Uwaga: zamieszczanie komentarzy zawierających linki do tej odpowiedzi przy wszystkich innych odpowiedziach można uznać za nadmierną autopromocję, a próba edytowania odpowiedzi jest wandalizmem. Twoje komentarze zostały usunięte i nie wprowadzaj więcej takich zmian.
Brad Larson