Tải tệp JSON cục bộ vào biến


113

Tôi đang cố gắng tải tệp .json vào một biến trong javascript, nhưng tôi không thể làm cho nó hoạt động. Chắc chỉ là một lỗi nhỏ nhưng tôi không tìm ra được.

Mọi thứ hoạt động tốt khi tôi sử dụng dữ liệu tĩnh như thế này:

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

Tôi đặt mọi thứ có {}trong một content.jsontệp và cố gắng tải nó vào một biến JavaScript cục bộ như được giải thích ở đây: tải json vào biến .

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

Tôi đã chạy nó với trình gỡ lỗi Chrome và nó luôn cho tôi biết rằng giá trị của biến jsonnull. Các content.jsoncư trú tập tin trong cùng thư mục với file .js mà các cuộc gọi nó.

Tôi đã bỏ lỡ cái gì?


1
Url tệp của bạn /content.jsoncó nghĩa là tệp đó ở cấp gốc của ứng dụng web của bạn. Thay đổi thành content.json(không có dấu gạch chéo) để trỏ nó vào cùng một thư mục nơi tệp script của bạn được đặt. Chỉ trong trường hợp nếu tệp script của bạn nằm trong thư mục cấp gốc, nó sẽ hoạt động.
Samich

cư trú tập tin trong WebContent \ JIT \ content.json .. Tôi cố gắng 'url': "/WebContent/jit/content.json", nhưng vẫn biến là null
PogoMips

Câu trả lời:


38

Nếu bạn dán content.jsontrực tiếp đối tượng của mình vào thì đó là JSON không hợp lệ. Các khóa giá trị JSON phải được đặt trong dấu ngoặc kép ( "không phải ') trừ khi giá trị là số, boolean nullhoặc hỗn hợp (mảng hoặc đối tượng). JSON không được chứa các hàm hoặc undefinedgiá trị. Dưới đây là đối tượng của bạn là JSON hợp lệ.

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

Bạn cũng đã có thêm }.


1
Tôi không thể tin rằng nó đã sửa nó .. tại sao nó sẽ hoạt động được nhúng trực tiếp vào tệp .js mà không có dấu ngoặc kép, nhưng không phải trong tệp .json? Điều đó không có ý nghĩa gì ...
PogoMips

16
@ user1695165 - json và một đối tượng javascript là hai thứ khác nhau, chúng trông giống nhau.
adeneo

2
@Kevin B "... trừ khi giá trị là số [hoặc boolean]."
Jacob Beauchamp,

1
Chỉ một mẹo nhỏ: bạn có thể sử dụng trình xác thực json như jsonlint.com để kiểm tra dữ liệu json của bạn trước khi sử dụng.
Marco Panichi

129

Giải pháp của tôi, như đã trả lời ở đây , là sử dụng:

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

Tệp chỉ được tải một lần, các yêu cầu khác sử dụng bộ nhớ đệm.

chỉnh sửa Để tránh bộ nhớ đệm, đây là chức năng trợ giúp từ bài đăng blog này được đưa ra trong các nhận xét, sử dụng fsmô-đun:

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

47
Chỉ muốn xác định rằng giải pháp này yêu cầu một thư viện bổ sung có tên là RequestJS .
Luis Kabongo,

4
Làm thế nào để tránh bộ nhớ đệm?
nono

2
Không được khuyến nghị theo Guilherme Oenning goenning.net/2016/04/14/stop-reading-json-files-with-require
Sangimed

2
TLDR; bộ nhớ đệm ảnh hưởng đến anh ta trong các bài kiểm tra đơn vị và do đó anh ta cung cấp một chức năng trợ giúp để tránh bộ nhớ đệm (ping @nono).
Ehvince

@Ehvince Ồ, tôi không nhận thấy điều đó vì tôi đã không đọc toàn bộ bài báo. Cảm ơn bạn :-)
Sangimed 19/03/18

50

Đối với ES6 / ES2015, bạn có thể nhập trực tiếp như:

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


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

Nếu bạn sử dụng Typescript, bạn có thể khai báo mô-đun json như:

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

Vì Typecript 2.9+ nên bạn có thể thêm - giải quyết trình biên dịch SolsonModuleOptions trongtsconfig.json

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

5
nhập không hoạt động trong Chrome v72 - vẫnUncaught SyntaxError: Unexpected token *
1000Gbps

2
Khi tôi sử dụng này, có vẻ như datalà một mô-đun nhưng data.defaultlà đối tượng
Dustin Michels

1
Tôi đã cố gắng chạy điều này trong bảng điều khiển, nhưng không thành công. Điều này không hoạt động với nút v12.4.0, với nút babel 6.26.0. Tôi luôn nhận đượcSyntaxError: Unexpected token *
mario199

2
đối với ES6 / ES2015, bạn có thể nhập trực tiếp: Có vẻ như tôi gặp lỗi bảng điều khiển khi thực hiện import * as data from './example.json'do lỗi kiểu mime.
Fallenreaper vào

nếu tôi sử dụng import * as data from './example.json';thì datachỉ là mô-đun, nhưng data.defaultlà đối tượng. Nhưng khi tôi sử dụng import data from './example.json';thì datalà đối tượng, có thể ứng dụng nhiều hơn
Nel

4

Có hai vấn đề có thể xảy ra:

  1. AJAX là không đồng bộ, vì vậy jsonsẽ không được xác định khi bạn quay lại từ hàm bên ngoài. Khi tệp đã được tải, chức năng gọi lại sẽ thiết lậpjson thành một giá trị nào đó nhưng lúc đó, không ai quan tâm nữa.

    Tôi thấy rằng bạn đã cố gắng khắc phục điều này với 'async': false. Để kiểm tra xem điều này có hoạt động hay không, hãy thêm dòng này vào mã và kiểm tra bảng điều khiển của trình duyệt của bạn:

    console.log(['json', json]);
  2. Đường dẫn có thể sai. Sử dụng cùng một đường dẫn mà bạn đã sử dụng để tải tập lệnh của mình trong tài liệu HTML. Vì vậy, nếu tập lệnh của bạn là js/script.js, hãy sử dụngjs/content.json

    Một số trình duyệt có thể cho bạn biết họ đã cố gắng truy cập vào URL nào và quá trình đó diễn ra như thế nào (mã thành công / lỗi, tiêu đề HTML, v.v.). Kiểm tra các công cụ phát triển của trình duyệt của bạn để xem điều gì sẽ xảy ra.


Có thể phiên bản jquery của anh ấy chưa hỗ trợ điều này? Tôi đã cải thiện từ ngữ.
Aaron Digulla

4

Việc xây dựng trong Node.js mô-đun fs sẽ thực hiện điều đó một cách không đồng bộ hoặc đồng bộ tùy thuộc vào nhu cầu của bạn.

Bạn có thể tải nó bằng cách sử dụng var fs = require('fs');

Không đồng bộ

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

Đồng bộ

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

-1

Đối với định dạng json đã cho như trong tệp ~ / my-app / src / db / abc.json:

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

inorder để nhập vào tệp .js như ~ / 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;

Đầu ra:

Ankit Aditi Avani

Đây là câu trả lời cho một câu hỏi không phải là câu hỏi ở đây.
Kevin B

@KevinB theo giải thích của tôi, tôi đã nhập tệp .json sang tệp .js. Điều này đã giúp tôi tải tệp json vào const json. Từ đây, tôi có thể sử dụng từ điển json sau cho các thuộc tính người dùng và như vậy.
Ank_247shbm

Điều đó thật tuyệt, tuy nhiên, câu hỏi này là về một người dùng đang cố gắng sao chép một đối tượng theo nghĩa đen vào tệp .json mà sau đó họ tải vào bằng ajax, chỉ có điều, đối tượng của họ có định dạng không hợp lệ cho JSON. Trong một số trường hợp, cài đặt react và import điều này với request chắc chắn sẽ hoạt động, nhưng nó không thực sự hữu ích trong trường hợp này.
Kevin B

Xin lưu ý: việc đăng nhận xét liên kết đến câu trả lời này trên tất cả các câu trả lời khác có thể bị coi là tự quảng cáo quá mức và việc cố gắng chỉnh sửa câu trả lời là hành vi phá hoại. Nhận xét của bạn đã bị xóa và vui lòng không thực hiện các chỉnh sửa như thế này nữa.
Brad Larson

Cảm ơn là công việc tuyệt vời cho tôi!
Qui-Gon Jinn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.