Muat file JSON lokal ke dalam variabel

113

Saya mencoba memuat file .json ke dalam variabel di javascript, tetapi saya tidak bisa membuatnya berfungsi. Ini mungkin hanya kesalahan kecil tetapi saya tidak dapat menemukannya.

Semuanya berfungsi dengan baik ketika saya menggunakan data statis seperti ini:

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

Saya meletakkan semua yang ada di {}dalam content.jsonfile dan mencoba memuatnya ke variabel JavaScript lokal seperti yang dijelaskan di sini: muat json ke variabel .

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

Saya menjalankannya dengan debugger Chrome dan selalu memberi tahu saya bahwa nilai variabelnya jsonadalah null. The content.jsonberkas berada dalam direktori yang sama dengan file js yang menyebutnya.

Apa yang saya lewatkan?

PogoMips
sumber
1
Url file Anda /content.jsonartinya file tersebut berada di level root aplikasi web Anda. Ubah ke content.json(tanpa garis miring) untuk mengarahkannya ke direktori yang sama tempat file skrip Anda ditempatkan. Hanya dalam kasus jika file skrip Anda ada di direktori level root, itu akan berfungsi.
Samich
file tersebut berada di WebContent \ jit \ content.json .. Saya mencoba 'url': "/WebContent/jit/content.json", tetapi variabelnya tetap null
PogoMips

Jawaban:

38

Jika Anda menempelkan objek Anda content.jsonsecara langsung, itu adalah JSON yang tidak valid. Kunci dan nilai JSON harus dibungkus dengan tanda kutip ganda ( "bukan ') kecuali nilainya adalah numerik, boolean null, atau komposit (larik atau objek). JSON tidak boleh berisi fungsi atau undefinednilai. Di bawah ini adalah objek Anda sebagai JSON yang valid.

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

Anda juga punya ekstra }.

Kevin B
sumber
1
Saya tidak percaya itu memperbaikinya .. mengapa itu berfungsi langsung tertanam di file .js tanpa tanda kutip ganda, tetapi tidak di file .json? Itu tidak masuk akal ...
PogoMips
16
@ user1695165 - json dan objek javascript adalah dua hal yang berbeda, hanya terlihat sama.
adeneo
2
@Kevin B "... kecuali nilainya numerik [atau bean]."
Jacob Beauchamp
1
Hanya tip: Anda dapat menggunakan validator json seperti jsonlint.com untuk memeriksa data json Anda sebelum menggunakannya.
Marco Panichi
129

Solusi saya, seperti yang dijawab di sini , adalah menggunakan:

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

File dimuat hanya sekali, permintaan lebih lanjut menggunakan cache.

edit Untuk menghindari caching, inilah fungsi helper dari blogpost ini yang diberikan di komentar, menggunakan fsmodul:

var readJson = (path, cb) => {
  fs.readFile(require.resolve(path), (err, data) => {
    if (err)
      cb(err)
    else
      cb(null, JSON.parse(data))
  })
}
Ehvince
sumber
48
Hanya ingin menentukan bahwa solusi ini memerlukan pustaka tambahan bernama RequireJS .
Luis Kabongo
4
Bagaimana cara menghindari caching?
bukan
2
Tidak direkomendasikan menurut Guilherme Oenning goenning.net/2016/04/14/stop-reading-json-files-with-require
Sangimed
2
TLDR; caching mengenainya di unit test dan dia memberikan fungsi pembantu untuk menghindari caching (ping @nono).
Ehvince
@Ehvince Oh, saya tidak menyadarinya karena saya tidak membaca seluruh artikel. Terima kasih :-)
Sangimed
50

Untuk ES6 / ES2015 Anda dapat mengimpor langsung seperti:

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


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

Jika Anda menggunakan Typecript, Anda dapat mendeklarasikan modul json seperti:

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

Sejak Typecript 2.9+ Anda dapat menambahkan - resolJsonModule compilerOptions ditsconfig.json

{
  "compilerOptions": {
    "target": "es5",
     ...
    "resolveJsonModule": true,
     ...
  },
  ...
}
Roy kecil
sumber
5
impor tidak berfungsi di Chrome v72 - masihUncaught SyntaxError: Unexpected token *
1000Gbps
2
Ketika saya menggunakan ini, tampaknya itu dataadalah modul tetapi data.defaultobjeknya
Dustin Michels
1
Saya mencoba menjalankan ini di konsol, tetapi tidak berhasil. Ini tidak berfungsi dengan node v12.4.0, dengan babel-node 6.26.0. Saya selalu mendapatkanSyntaxError: Unexpected token *
mario199
2
untuk ES6 / ES2015 Anda dapat mengimpor secara langsung: Sepertinya saya mendapatkan kesalahan konsol saat melakukan import * as data from './example.json'karena kesalahan jenis mime.
Fallenreaper
jika saya gunakan import * as data from './example.json';maka datahanya modul, tetapi data.defaultobjeknya. Tetapi ketika saya menggunakan import data from './example.json';maka dataadalah objeknya, yang lebih dapat diterapkan
Nel
4

Ada dua kemungkinan masalah:

  1. AJAX tidak sinkron, jadi jsontidak akan ditentukan saat Anda kembali dari fungsi luar. Saat file telah dimuat, fungsi panggilan balik akan disetel jsonke beberapa nilai tetapi pada saat itu, tidak ada yang peduli lagi.

    Saya melihat bahwa Anda mencoba memperbaikinya dengan 'async': false. Untuk memeriksa apakah ini berfungsi, tambahkan baris ini ke kode dan periksa konsol browser Anda:

    console.log(['json', json]);
  2. Jalannya mungkin salah. Gunakan jalur yang sama yang Anda gunakan untuk memuat skrip Anda di dokumen HTML. Jadi, jika skrip Anda adalah js/script.js, gunakanjs/content.json

    Beberapa browser dapat menunjukkan kepada Anda URL mana yang mereka coba akses dan bagaimana hasilnya (kode sukses / kesalahan, header HTML, dll). Periksa alat pengembangan browser Anda untuk melihat apa yang terjadi.

Aaron Digulla
sumber
Mungkin versi jquerynya belum mendukung ini? Saya telah memperbaiki kata-katanya.
Aaron Digulla
4

Built-in node.js modul fs akan melakukannya secara asinkron atau sinkron tergantung pada kebutuhan Anda.

Anda dapat memuatnya menggunakan var fs = require('fs');

Asinkron

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

Sinkronis

var json = JSON.parse(fs.readFileSync('./content.json').toString());
Arnaud M.
sumber
-1

Untuk format json yang diberikan seperti pada file ~ / my-app / src / db / abc.json:

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

inorder untuk mengimpor ke file .js seperti ~ / 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;

Keluaran:

Ankit Aditi Avani
Ank_247shbm
sumber
Ini adalah jawaban untuk pertanyaan yang bukan yang ditanyakan di sini.
Kevin B
@KevinB menurut penjelasan saya, saya mengimpor file .json ke file .js. Ini membantu saya memuat json-file ke const json. Dari sini, saya dapat menggunakan kamus json berikut untuk atribut pengguna dan sebagainya.
Ank_247shbm
Itu bagus, bagaimanapun, pertanyaan ini adalah tentang pengguna yang mencoba menyalin literal objek ke dalam file .json yang kemudian mereka muat dengan ajax, hanya saja, literal objek mereka dalam format yang tidak valid untuk JSON. Sementara menginstal react dan mengimpor ini dengan membutuhkan pasti akan berfungsi dalam beberapa kasus, itu tidak benar-benar membantu kasus ini .
Kevin B
Sebagai catatan: memposting komentar yang menautkan ke jawaban ini di semua jawaban lain dapat dianggap sebagai promosi diri yang berlebihan, dan mencoba mengedit jawaban adalah tindakan vandalisme. Komentar Anda telah dihapus, dan mohon jangan melakukan pengeditan seperti ini lagi.
Brad Larson
Terima kasih, itu bagus untuk saya!
Qui-Gon Jinn