HTML / Javascript: วิธีเข้าถึงข้อมูล JSON ที่โหลดในแท็กสคริปต์ด้วยชุด src


91

ฉันมีไฟล์ JSON ที่ฉันสร้างในเซิร์ฟเวอร์ที่ฉันต้องการให้เข้าถึงได้บนไคลเอนต์เนื่องจากสามารถดูเพจได้ โดยพื้นฐานแล้วสิ่งที่ฉันต้องการบรรลุคือ:

ฉันมีแท็กต่อไปนี้ที่ประกาศในเอกสาร html ของฉัน:

<script id="test" type="application/json" src="http://myresources/stuf.json">

ไฟล์ที่อ้างถึงในแหล่งที่มามีข้อมูล JSON อย่างที่ฉันเห็นมีการดาวน์โหลดข้อมูลเช่นเดียวกับที่เกิดขึ้นกับสคริปต์

ตอนนี้ฉันจะเข้าถึงใน Javascript ได้อย่างไร ฉันได้พยายามเข้าถึงแท็กสคริปต์ทั้งที่มีและไม่มี jQuery โดยใช้วิธีการมากมายเพื่อพยายามรับข้อมูล JSON ของฉัน แต่ก็ไม่ได้ผล การใช้งานinnerHTMLจะได้ผลหากข้อมูล json ถูกเขียนแบบอินไลน์ในสคริปต์ ซึ่งมันไม่ใช่และไม่ใช่สิ่งที่ฉันพยายามจะบรรลุ

คำขอ JSON ระยะไกลหลังจากโหลดหน้าไม่ใช่ตัวเลือกในกรณีที่คุณต้องการแนะนำเช่นนั้น


3
แทนที่จะเป็นไฟล์ json ให้สร้างเป็นไฟล์ javascript ที่กำหนดอ็อบเจ็กต์ให้กับตัวแปร อีกวิธีหนึ่งคือการใช้ ajax
Asad Saeeduddin

3
คำแนะนำแรกคือการนำไปใช้งานในปัจจุบัน ฉันไม่อยากทำเพราะฉันกำลังใช้พฤติกรรมเพื่อส่งมอบโครงสร้าง ฉันต้องการใช้โครงสร้างสำหรับโครงสร้าง (ถ้าฉันต้องการ JSON ฉันจะได้รับ JSON) ไม่ต้องการคำแนะนำที่สอง (ฉันต้องการข้อมูลนี้สำหรับขั้นตอนการเริ่มต้น)
ChuckE

1
@ChuckE ผ่าน<script>แท็กหรือผ่าน AJAX คุณจะต้องรอให้คำขอ HTTP เพิ่มเติมดำเนินการให้เสร็จสิ้น เบราว์เซอร์จะไม่อนุญาตให้คุณอ่านเนื้อหาสคริปต์หากคุณดึงข้อมูลด้วยแอตทริบิวต์ "src" ดังนั้นทางเลือกเดียวของคุณคือส่งคำขอ AJAX
Pointy

3
@Pointy ผ่านแท็ก <script> สิ่งต่างๆจะได้รับการประเมินทันทีที่ดาวน์โหลด หากฉันวางสคริปต์ json ไว้ก่อนสคริปต์ js ของฉันข้อมูลสคริปต์ json จะได้รับการประเมินก่อนข้อมูลสคริปต์ js นั่นหมายความว่าฉันจะไม่รอข้อมูลมีอยู่แล้ว เกี่ยวกับเรื่องนี้เป็นทางเลือกเดียวของฉันฉันต้องการดูเอกสารอย่างเป็นทางการก่อนที่จะตกลงกับคุณ (ไม่ได้บอกว่าคุณผิดนั่นคือเหตุผลที่ฉันเขียนคำถาม)
ChuckE

2
"คำขอ JSON ระยะไกลหลังจากโหลดหน้าเว็บก็ไม่ใช่ตัวเลือกในกรณีที่คุณต้องการแนะนำเช่นนั้น" ... คำขอ JSON แตกต่างจากคำขอที่ส่งโดย a มาก<script src=""></script>อย่างไร พวกเขาทั้งสองจะทำการโทร GET กับเซิร์ฟเวอร์ของคุณ
Ben Lesh

คำตอบ:


116

คุณไม่สามารถโหลด JSON เช่นนั้นได้ขออภัย

ฉันรู้ว่าคุณกำลังคิดว่า "ทำไมฉันถึงใช้srcที่นี่ไม่ได้ฉันเคยเห็นอะไรแบบนี้ ... ":

<script id="myJson" type="application/json">
 { 
   name: 'Foo' 
 }
</script>

<script type="text/javascript">
    $(function() {
        var x = JSON.parse($('#myJson').html());
        alert(x.name); //Foo
     });
</script>

... พูดง่ายๆก็คือแท็กสคริปต์ถูก "ทำร้าย" ในฐานะผู้ถือข้อมูล คุณสามารถทำได้กับข้อมูลทุกประเภท ยกตัวอย่างเช่นจำนวนมากของแท็กสคริปต์เครื่องมือ templating ใช้ประโยชน์ในการถือแม่

คุณมีรายการตัวเลือกสั้น ๆ ในการโหลด JSON ของคุณจากไฟล์ระยะไกล:

  1. ใช้$.get('your.json')หรือวิธี AJAX อื่น ๆ
  2. เขียนไฟล์ที่ตั้งค่าตัวแปรส่วนกลางเป็น json ของคุณ (ดูเหมือนฮ็อกกี้)
  3. ดึงเข้าใน iframe ที่มองไม่เห็นจากนั้นขูดเนื้อหาหลังจากโหลดเสร็จแล้ว (ฉันเรียกโหมดนี้ว่า "1997 mode")
  4. ปรึกษานักบวชลัทธิวูดู

จุดสุดท้าย:

คำขอ JSON ระยะไกลหลังจากโหลดหน้าก็ไม่ใช่ตัวเลือกในกรณีที่คุณต้องการแนะนำเช่นนั้น

... นั่นไม่สมเหตุสมผลเลย ความแตกต่างระหว่างคำขอ AJAX และคำขอที่เบราว์เซอร์ส่งมาในขณะประมวลผลของคุณ<script src="">นั้นไม่มีอะไรเลย ทั้งคู่จะทำ GET กับทรัพยากร HTTP ไม่สนใจว่าจะทำเพราะแท็กสคริปต์หรือการเรียก AJAX และเซิร์ฟเวอร์ของคุณก็ไม่ได้เช่นกัน


5
คำตอบที่ดี เมื่อคุณพูดว่า "แท็กสคริปต์ถูก" ทำร้าย "คุณหมายความว่าเป็นการใช้แท็กสคริปต์ผิด (อาจจะไม่ผิด แต่" สร้างสรรค์ ") n ของคุณ 2 ตัวเลือกคือตัวเลือกที่เรามีอยู่แล้วในการผลิตฉันกำลังมองหาโซลูชัน json / no-js อย่างเคร่งครัดจากการทดลองที่บริสุทธิ์ (ฉันสบายดีที่มันเป็นไปไม่ได้ถ้าฉันแน่ใจ) เกี่ยวกับประเด็นสุดท้ายฉันต้องการข้อมูลนี้ก่อนเหตุการณ์ onload และฉันไม่ต้องการให้การเริ่มต้นทั้งหมดขึ้นอยู่กับคำขอแบบอะซิงโครนัสซึ่งอาจแตกต่างกันไปในเวลาที่เสร็จสมบูรณ์ นี่คือข้อแตกต่างที่สำคัญระหว่างการโทร Ajax และแท็กสคริปต์
ChuckE

1
ไม่ฉันไม่คิดว่ามัน "ผิด" ต่อคำว่า ... "สร้างสรรค์" น่าจะเป็นคำที่ดีสำหรับมัน หากการเขียน JSON ลงใน<script>แท็กเป็นไปได้จริงฉันจะไปเส้นทางนั้นฉันเดา
Ben Lesh

ใช่ความท้าทายทั้งหมดคือการโหลดโดยใช้แอตทริบิวต์แท็กสคริปต์ src และ "ทำให้สับสน" ข้อมูลนี้ในเอกสาร
ChuckE

คุณไม่สามารถซ่อนข้อมูลจากผู้ใช้ในแอปเบราว์เซอร์ฝั่งไคลเอ็นต์ได้ พวกเขาสามารถเข้าไปในเครื่องมือสำหรับนักพัฒนาของเบราว์เซอร์และตั้งค่าเบรกพอยต์ใน JavaScript และตรวจสอบวัตถุได้ตามต้องการ
Ben Lesh

1
@Jaydipsinh จากนั้นคุณต้องแก้ไขปัญหา CORS ของคุณและใช้ Ajax มีเหตุผลที่เบราว์เซอร์ไม่อนุญาตพฤติกรรมประเภทนี้ เบราว์เซอร์ส่วนใหญ่จะไม่ยอมให้คุณแฮ็คเส้นทาง CORS ด้วย iframe อีกต่อไป
Ben Lesh

14

อีกวิธีหนึ่งคือการใช้ภาษาสคริปต์ฝั่งเซิร์ฟเวอร์และรวม json-data แบบอินไลน์ นี่คือตัวอย่างที่ใช้ PHP:

<script id="data" type="application/json"><?php include('stuff.json'); ?></script>
<script>
var jsonData = JSON.parse(document.getElementById('data').textContent)
</script>

application/jsonตัวอย่างข้างต้นใช้แท็กสคริปต์พิเศษกับประเภท วิธีแก้ปัญหาที่ง่ายกว่านั้นคือการรวม JSON ลงใน JavaScript โดยตรง:

<script>var jsonData = <?php include('stuff.json');?>;</script>

ข้อดีของโซลูชันที่มีแท็กพิเศษคือโค้ด JavaScript และข้อมูล JSON จะถูกแยกออกจากกัน


+ สำหรับเนื้อหาข้อความ .html ใช้กับแท็กสคริปต์ไม่ได้สำหรับฉัน
Seth McClaine

9

ดูเหมือนว่าเป็นไปไม่ได้หรืออย่างน้อยก็ไม่รองรับ

จากข้อกำหนด HTML5 :

เมื่อใช้เพื่อรวมบล็อกข้อมูล (ซึ่งตรงข้ามกับสคริปต์) ข้อมูลจะต้องฝังอยู่ในบรรทัดรูปแบบของข้อมูลต้องกำหนดโดยใช้แอตทริบิวต์ type ไม่ต้องระบุแอตทริบิวต์ srcและเนื้อหาขององค์ประกอบสคริปต์ต้องเป็นไปตาม ตามข้อกำหนดที่กำหนดไว้สำหรับรูปแบบที่ใช้


1
ดูเหมือนจะเป็นนโยบายในการจัดการข้อมูลที่มีความละเอียดอ่อนมากกว่า JS และ CSS

5

แม้ว่าในปัจจุบันจะใช้scriptแท็กไม่ได้ แต่ก็เป็นไปได้iframeหากมาจากโดเมนเดียวกัน

<iframe
id="mySpecialId"
src="/my/link/to/some.json"
onload="(()=>{if(!window.jsonData){window.jsonData={}}try{window.jsonData[this.id]=JSON.parse(this.contentWindow.document.body.textContent.trim())}catch(e){console.warn(e)}this.remove();})();"
onerror="((err)=>console.warn(err))();"
style="display: none;"
></iframe>

หากต้องการใช้ข้างต้นเพียงแค่แทนที่idand srcattribute ด้วยสิ่งที่คุณต้องการ id(ซึ่งเราจะสมมติในสถานการณ์เช่นนี้เท่ากับmySpecialId) จะถูกนำมาใช้ในการจัดเก็บข้อมูลwindow.jsonData["mySpecialId"]ใน

กล่าวอีกนัยหนึ่งสำหรับ iframe ทุกตัวที่มีidและใช้onloadสคริปต์จะมีการโหลดข้อมูลนั้นพร้อมกันลงในwindow.jsonDataวัตถุภายใต้ที่idระบุ

ฉันทำสิ่งนี้เพื่อความสนุกสนานและเพื่อแสดงให้เห็นว่า "เป็นไปได้" แต่ฉันไม่แนะนำให้ใช้


นี่คือทางเลือกที่ใช้การโทรกลับแทน

<script>
    function someCallback(data){
        /** do something with data */
        console.log(data);

    }
    function jsonOnLoad(callback){
        const raw = this.contentWindow.document.body.textContent.trim();
        try {
          const data = JSON.parse(raw);
          /** do something with data */
          callback(data);
        }catch(e){
          console.warn(e.message);
        }
        this.remove();
    }
</script>
<!-- I frame with src pointing to json file on server, onload we apply "this" to have the iframe context, display none as we don't want to show the iframe -->
<iframe src="your/link/to/some.json" onload="jsonOnLoad.apply(this, someCallback)" style="display: none;"></iframe>

ผ่านการทดสอบใน chrome และควรทำงานใน firefox ไม่แน่ใจเกี่ยวกับ IE หรือ Safari


3

ฉันเห็นด้วยกับเบ็น คุณไม่สามารถโหลด / นำเข้าไฟล์ JSON แบบธรรมดา

แต่ถ้าคุณต้องการทำอย่างนั้นและมีความยืดหยุ่นในการอัปเดตไฟล์ json คุณสามารถทำได้

my-json.js

   var myJSON = {
      id: "12ws",
      name: "smith"
    }

index.html

<head>
  <script src="my-json.js"></script>
</head>
<body onload="document.getElementById('json-holder').innerHTML = JSON.stringify(myJSON);">
  <div id="json-holder"></div>
</body>

2

ตรวจสอบคำตอบนี้: https://stackoverflow.com/a/7346598/1764509

$.getJSON("test.json", function(json) {
    console.log(json); // this will show the info it in firebug console
});

3
$ .getJSON () เป็นการโทรแบบ ajax
Tobi G.

ฉันจะแสดงข้อมูลในไฟล์ HTML ที่เชื่อมโยงแทนคอนโซลได้อย่างไร
ที.

2

หากคุณต้องการโหลด JSON จากโดเมนอื่น: http://en.wikipedia.org/wiki/JSONP
อย่างไรก็ตามโปรดระวังการโจมตี XSSI ที่อาจเกิดขึ้น: https://www.scip.ch/en/?labs.20160414

หากเป็นโดเมนเดียวกันให้ใช้ Ajax


2
JSONP ไม่ทำงานกับผลลัพธ์ที่จัดรูปแบบ JSON นอกจากนี้พารามิเตอร์ JSONP ที่ส่งผ่านเป็นอาร์กิวเมนต์ไปยังสคริปต์ถูกกำหนดโดยเซิร์ฟเวอร์…ซึ่งคุณอาจไม่มีสิทธิ์เข้าถึง
e-sushi

1

วางสิ่งนี้ในไฟล์สคริปต์ของคุณ json-content.js

var mainjson = { your json data}

จากนั้นเรียกใช้จากแท็กสคริปต์

<script src="json-content.js"></script>

จากนั้นคุณสามารถใช้ในสคริปต์ถัดไป

<script>
console.log(mainjson)
</script>

0

อีกทางเลือกหนึ่งในการใช้ json ที่แน่นอนภายใน javascript เนื่องจากเป็น Javascript Object Notation คุณสามารถสร้างวัตถุของคุณได้โดยตรงด้วยสัญกรณ์ json หากคุณเก็บสิ่งนี้ไว้ในไฟล์. js คุณสามารถใช้วัตถุในแอปพลิเคชันของคุณได้ นี่เป็นตัวเลือกที่มีประโยชน์สำหรับฉันเมื่อฉันมีข้อมูล json แบบคงที่ซึ่งฉันต้องการแคชในไฟล์แยกจากแอพอื่น ๆ ของฉัน

    //Just hard code json directly within JS
    //here I create an object CLC that represents the json!
    $scope.CLC = {
        "ContentLayouts": [
            {
                "ContentLayoutID": 1,
                "ContentLayoutTitle": "Right",
                "ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/right.png",
                "ContentLayoutIndex": 0,
                "IsDefault": true
            },
            {
                "ContentLayoutID": 2,
                "ContentLayoutTitle": "Bottom",
                "ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/bottom.png",
                "ContentLayoutIndex": 1,
                "IsDefault": false
            },
            {
                "ContentLayoutID": 3,
                "ContentLayoutTitle": "Top",
                "ContentLayoutImageUrl": "/Wasabi/Common/gfx/layout/top.png",
                "ContentLayoutIndex": 2,
                "IsDefault": false
            }
        ]
    };
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.