Завантажте локальний файл JSON у змінну


113

Я намагаюся завантажити файл .json в змінну в JavaScript, але я не можу змусити його працювати. Це, мабуть, лише незначна помилка, але я не можу її знайти.

Все працює чудово, коли я використовую статичні дані на зразок цього:

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

Я поставив все , що в {}в content.jsonфайл і спробував завантажити це в локальній змінній JavaScript , як описано тут: навантаження в JSON змінної .

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

Я запустив його за допомогою налагоджувача Chrome, і він завжди говорить мені, що значення змінної jsonє null. У content.jsonфайл знаходиться в тому ж каталозі, що і файл .js , який викликає його.

Що я пропустив?


1
Ваш файл URL - /content.jsonце означає, що цей файл знаходиться на кореневому рівні вашого веб-програми. Перейдіть на content.json(без косої риски), щоб вказати його в тому самому каталозі, де розміщений файл вашого сценарію. Тільки у випадку, якщо ваш скрипт-файл знаходиться в каталозі кореневого рівня, він буде працювати.
Саміч

файл знаходиться у WebContent \ jit \ content.json .. Я спробував 'url': "/WebContent/jit/content.json", але все ж змінна є нульовою
PogoMips

Відповіді:


38

Якщо ви вставили об'єкт content.jsonбезпосередньо, це недійсний JSON. Ключі та значення JSON повинні бути загорнуті у подвійні лапки ( "не '), якщо значення не є числовим, булевим null, або складеним (масив або об'єкт). JSON не може містити функції або undefinedзначення. Нижче ваш об’єкт як дійсний JSON.

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

У вас також був додатковий }.


1
Я не можу повірити, що це виправлено .. чому б він працював безпосередньо вбудований у файл .js без подвійних лапок, але не у файл .json? Це не має сенсу ...
PogoMips

16
@ user1695165 - json та об’єкт javascript - це дві різні речі, вони просто виглядають однаково.
adeneo

2
@Kevin B "... якщо значення не є числовим [або булевим]."
Джейкоб Бошамп

1
Лише порада: ви можете використовувати валідатор json, як jsonlint.com , щоб перевірити свої дані json перед його використанням.
Марко Панічі

129

Моє рішення, як тут відповіли , полягає у використанні:

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

Файл завантажується лише один раз, додаткові запити використовують кеш.

редагування Щоб уникнути кешування, ось функція помічника з цього блогу, розміщена в коментарях, за допомогою fsмодуля:

var readJson = (path, cb) => {
  fs.readFile(require.resolve(path), (err, data) => {
    if (err)
      cb(err)
    else
      cb(null, JSON.parse(data))
  })
}

48
Просто хотілося вказати, що для цього рішення потрібна додаткова бібліотека під назвою RequireJS .
Луїс Кабонго

4
Як уникнути кешування?
nono

2
Не рекомендується згідно з Guilherme Oenning goenning.net/2016/04/14/stop-reading-json-files-with-require
Sangimed

2
TLDR; кешування вдарило його в одиничних тестах, і тому він надає функцію помічника, щоб уникнути кешування (ping @nono).
Переконати

@ Переконання О, я не помітив цього, оскільки не прочитав всю статтю. Дякую :-)
Сангімед

50

Для ES6 / ES2015 можна імпортувати безпосередньо так:

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


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

Якщо ви використовуєте Typescript, ви можете оголосити модуль json таким чином:

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

Оскільки Typescript 2.9+ ви можете додати - resolutionJsonModule compilerOptions в Windowstsconfig.json

{
  "compilerOptions": {
    "target": "es5",
     ...
    "resolveJsonModule": true,
     ...
  },
  ...
}

5
імпорт не працює в Chrome v72 - досіUncaught SyntaxError: Unexpected token *
1000Gbps

2
Коли я користуюсь цим, здається data, це модуль, але data.defaultце об'єкт
Дастін Міхельс,

1
Я намагався запустити це в консолі, але без успіху. Це не працює з вузлом v12.4.0, з babel-вузлом 6.26.0. Я завжди отримуюSyntaxError: Unexpected token *
mario199

2
для ES6 / ES2015 ви можете імпортувати безпосередньо: Здається, що я отримую помилку консолі при виконанні import * as data from './example.json'помилки типу mime.
Fallenreaper

якщо я використовую, import * as data from './example.json';то dataце просто модуль, але data.defaultце об'єкт. Але коли я використовую, import data from './example.json';то dataє об'єкт, який можна застосувати більше
Nel

4

Можливі дві проблеми:

  1. AJAX асинхронний, тому jsonбуде невизначений, коли ви повернетесь із зовнішньої функції. Коли файл завантажений, функція зворотного дзвінка встановить jsonдеяке значення, але в той час вже ніхто не переймається.

    Я бачу, що ви намагалися це виправити 'async': false. Щоб перевірити, чи працює це, додайте цей рядок до коду та перевірте консоль браузера:

    console.log(['json', json]);
  2. Шлях може бути неправильним. Використовуйте той самий шлях, який ви використовували для завантаження сценарію в документ HTML. Тож якщо ваш сценарій є js/script.js, використовуйтеjs/content.json

    Деякі веб-переглядачі можуть показати вам, до яких URL-адрес вони намагалися отримати доступ і як це пішло (коди успіху / помилок, HTML заголовки тощо). Перевірте інструменти розробки веб-переглядача, щоб побачити, що відбувається.


Можливо, його версія jquery ще не підтримує це? Я вдосконалив формулювання.
Аарон Дігулла

4

Вбудований модуль node.js fs зробить це або асинхронно, або синхронно, залежно від ваших потреб.

Ви можете завантажити його за допомогою var fs = require('fs');

Асинхронний

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

Синхронний

var json = JSON.parse(fs.readFileSync('./content.json').toString());

-1

Для заданого формату json, як у файлі ~ / my-app / src / db / abc.json:

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

порядок імпорту у файл .js, наприклад ~ / 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;

Вихід:

Ankit Aditi Avani

Це відповідь на питання, яке тут не задається.
Кевін Б

@KevinB, відповідно до мого пояснення, я імпортував .json файл у .js файл. Це допомогло мені завантажити json-файл до const json. Звідси я можу використовувати наступний словник json для атрибутів користувача тощо.
Ank_247shbm

Це чудово, однак, це питання стосується того, що користувач намагається скопіювати об'єкт-літерал у файл .json, який він завантажує разом з ajax, лише їх об'єктний літерал був у форматі, недійсному для JSON. Хоча установка реагувати та імпортувати це з вимогою, безумовно, спрацює в деяких випадках, це не дуже допомагає цій справі.
Кевін Б

Як зауваження: розміщення коментарів, що посилаються на цю відповідь на всі інші відповіді, можна вважати надмірною саморекламою, а спроба редагувати відповіді - вандалізмом. Ваші коментарі видалено, і, будь ласка, більше не змінюйте подібні зміни.
Бред Ларсон

Дякую, це чудово працює для мене!
Qui-Gon Jinn
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.