โหลดไฟล์ 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 อยู่แฟ้มในไดเรกทอรีเดียวกันกับแฟ้ม .js ที่เรียกมันว่าnullcontent.json

ฉันพลาดอะไร?


1
URL ไฟล์ของคุณ/content.jsonซึ่งหมายความว่าไฟล์นั้นอยู่ในระดับรูทของเว็บแอปของคุณ เปลี่ยนเป็นcontent.json(ไม่มีเครื่องหมายทับ) เพื่อชี้ไปยังไดเร็กทอรีเดียวกันกับที่วางไฟล์สคริปต์ของคุณ เฉพาะในกรณีที่ไฟล์สคริปต์ของคุณอยู่ในไดเร็กทอรีระดับรูทมันจะใช้งานได้
Samich

ไฟล์อยู่ใน WebContent \ jit \ content.json .. ฉันลอง 'url': "/WebContent/jit/content.json" แต่ตัวแปรยังคงเป็นโมฆะ
PogoMips

คำตอบ:


39

หากคุณวางวัตถุลงใน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 "... เว้นแต่ค่าจะเป็นตัวเลข [หรือบูลีน]"
Jacob Beauchamp

1
เพียงเคล็ดลับ: คุณสามารถใช้โปรแกรมตรวจสอบความถูกต้องของ json เช่นjsonlint.comเพื่อตรวจสอบข้อมูล json ของคุณก่อนใช้งาน
Marco Panichi

130

วิธีแก้ปัญหาของฉันตามคำตอบที่นี่คือการใช้:

    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))
  })
}

49
แค่อยากจะระบุว่าการแก้ปัญหานี้ต้องใช้ห้องสมุดชื่อเพิ่มเติมRequireJS
Luis Kabongo

4
จะหลีกเลี่ยงการแคชได้อย่างไร?
nono

2
ไม่แนะนำตาม Guilherme Oenning goenning.net/2016/04/14/stop-reading-json-files-with-require
Sangimed

2
TLDR; การแคชโจมตีเขาในการทดสอบหน่วยดังนั้นเขาจึงให้ฟังก์ชันตัวช่วยเพื่อหลีกเลี่ยงการแคช (ping @nono)
Ehvince

@Ehvince โอ้ฉันไม่ได้สังเกตว่าเพราะฉันไม่ได้อ่านบทความทั้งหมด ขอบคุณ :-)
Sangimed

53

สำหรับ 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+ คุณสามารถเพิ่ม - คอมไพเลอร์fixJsonModule ตัวเลือกในtsconfig.json

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

5
การนำเข้าไม่ทำงานใน Chrome v72 - ยังคงเป็นUncaught SyntaxError: Unexpected token *
1000Gbps

2
เมื่อฉันใช้สิ่งนี้ดูเหมือนว่าdataเป็นโมดูล แต่data.defaultเป็นวัตถุ
Dustin Michels

1
ฉันพยายามเรียกใช้สิ่งนี้ในคอนโซล แต่ไม่ประสบความสำเร็จ สิ่งนี้ใช้ไม่ได้กับโหนด v12.4.0 กับ babel-node 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 เวอร์ชันของเขายังไม่รองรับสิ่งนี้ ฉันได้ปรับปรุงถ้อยคำแล้ว
Aaron Digulla

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());

0

สำหรับรูปแบบ 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

นี่คือคำตอบสำหรับคำถามที่ไม่ใช่คำถามที่ถามที่นี่
Kevin B

@KevinB ตามคำอธิบายของฉันฉันนำเข้าไฟล์. json ไปยังไฟล์. js สิ่งนี้ช่วยฉันในการโหลดไฟล์ json เป็น const json จากที่นี่ฉันสามารถใช้พจนานุกรม json ต่อไปนี้สำหรับคุณลักษณะของผู้ใช้และอื่น ๆ
Ank_247shbm

เป็นเรื่องที่ดีอย่างไรก็ตามคำถามนี้เกี่ยวกับผู้ใช้ที่พยายามคัดลอกอ็อบเจกต์ลิเทอรัลลงในไฟล์. json จากนั้นพวกเขาโหลดด้วย ajax เท่านั้นอ็อบเจ็กต์ลิเทอรัลของพวกเขาอยู่ในรูปแบบที่ไม่ถูกต้องสำหรับ JSON ในขณะที่ติดตั้งการตอบสนองและนำเข้าสิ่งนี้ด้วยความต้องการจะใช้งานได้อย่างแน่นอนในบางกรณีก็ไม่ได้ช่วยอะไรในกรณีนี้
Kevin B

หมายเหตุ: การโพสต์ความคิดเห็นที่ลิงก์ไปยังคำตอบนี้ในคำตอบอื่น ๆ ทั้งหมดถือได้ว่าเป็นการส่งเสริมตนเองมากเกินไปและการพยายามแก้ไขคำตอบถือเป็นการป่าเถื่อน ความคิดเห็นของคุณถูกลบออกแล้วโปรดอย่าทำการแก้ไขเช่นนี้อีก
Brad Larson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.