วิธีรับ JSON จาก URL ใน JavaScript


166

URL นี้ส่งคืน JSON:

{
  query: {
    count: 1,
    created: "2015-12-09T17:12:09Z",
    lang: "en-US",
    diagnostics: {},
    ...
  }
}

ฉันลองสิ่งนี้และมันไม่ทำงาน:

responseObj = readJsonFromUrl('http://query.yahooapis.com/v1/publ...');
var count = responseObj.query.count;

console.log(count) // should be 1

ฉันจะรับวัตถุ JavaScript จากการตอบสนอง JSON ของ URL นี้ได้อย่างไร


1
สิ่งที่คุณมีคือ URL ที่ส่งคืนการตอบกลับที่มีสตริง JSON คุณกำลังถามวิธีขอบางสิ่งจาก URL หรือไม่? เพราะนั่นจะขึ้นอยู่กับภาษาหรือเครื่องมือที่คุณใช้เป็นอย่างมาก เฉพาะเจาะจงมากขึ้น.
jrajav

1
คำถามนี้ทำให้เกิดความสับสน คุณไม่ได้รับวัตถุ JSON โดยใช้ URL ที่คุณกล่าวถึง? คุณหมายถึงอะไรโดยรับวัตถุ JSON จาก URL? กรุณาชี้แจง
Steven

คำตอบ:


166

คุณสามารถใช้.getJSON()ฟังก์ชั่นjQuery :

$.getJSON('http://query.yahooapis.com/v1/public/yql?q=select%20%2a%20from%20yahoo.finance.quotes%20WHERE%20symbol%3D%27WRC%27&format=json&diagnostics=true&env=store://datatables.org/alltableswithkeys&callback', function(data) {
    // JSON result in `data` variable
});

หากคุณไม่ต้องการใช้ jQuery คุณควรดูคำตอบนี้เพื่อหาโซลูชัน JS บริสุทธิ์: https://stackoverflow.com/a/2499647/1361042


14
จุดเล็ก ๆ น้อย ๆ แต่อาจจะชัดเจนขึ้นถ้าระบุว่า 'JSON อยู่ในdataตัวแปร'
Nathan Hornby

2
ตัวอย่าง JavaScript บริสุทธิ์ที่คุณเลือกใช้สำหรับ JSONP ซึ่งไม่สามารถใช้ได้กับคำถาม
SArcher

137

ถ้าคุณต้องการที่จะทำมันในจาวาสคริปต์ธรรมดาคุณสามารถกำหนดฟังก์ชั่นเช่นนี้:

var getJSON = function(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.responseType = 'json';
    xhr.onload = function() {
      var status = xhr.status;
      if (status === 200) {
        callback(null, xhr.response);
      } else {
        callback(status, xhr.response);
      }
    };
    xhr.send();
};

และใช้มันเช่นนี้

getJSON('http://query.yahooapis.com/v1/public/yql?q=select%20%2a%20from%20yahoo.finance.quotes%20WHERE%20symbol%3D%27WRC%27&format=json&diagnostics=true&env=store://datatables.org/alltableswithkeys&callback',
function(err, data) {
  if (err !== null) {
    alert('Something went wrong: ' + err);
  } else {
    alert('Your query count: ' + data.query.count);
  }
});

โปรดทราบว่าdataเป็นวัตถุเพื่อให้คุณสามารถเข้าถึงคุณลักษณะได้โดยไม่ต้องแยกวิเคราะห์


ทำไมใช้.onload = function() {เมื่อคุณสามารถใช้.onreadystatechange = function() { if (xhr.readState === 4) {ฉันหมายความว่ามันสั้นกว่า แต่คุณกำลังเสียสละการสนับสนุนมากมายสำหรับการบันทึกอักขระสองสามตัว นี่ไม่ใช่ code-golf
Downgoat

4
มันสั้นไม่เพียง แต่ดูเหมือนว่าจะน่าเชื่อถือมากขึ้นตามโพสต์นี้ และcaniuse.comบอกว่ารองรับทุกอย่างยกเว้น IE8 ตราบใดที่คุณไม่จำเป็นต้องรองรับ IE8 ฉันไม่เห็นว่าทำไมคุณไม่ใช้ onload
Robin Hartmann

@ MikeySkullivan ฉันต้องการทราบสิ่งหนึ่งว่าทำไมฉันถึงได้รับ responseText และ responseXML ตามที่ไม่ได้กำหนดแม้ว่าสถานะการตอบกลับ = 200?
hrushi

1
@hrushi หากพวกเขาไม่ได้กำหนดคุณจะเข้าถึงพวกเขาในทางที่ผิดหรือในบริบทที่ผิด จำไว้ว่าคุณต้องใช้ xhr.responseText และ xhr.responseXML และจะใช้ได้เฉพาะในบล็อกการกำหนดฟังก์ชันของ getJSON ไม่ใช่ด้านนอก
Robin Hartmann

2
@MitchellD คุณใช้ Node.js หรือไม่ จากนั้นจะดูมากกว่าที่นี่ แต่ครั้งต่อไปลองใช้ Google เพื่อหาข้อผิดพลาดก่อนลิงค์ที่ฉันโพสต์เป็นผลลัพธ์แรกที่เกิดขึ้นเมื่อฉันพิมพ์ข้อผิดพลาดลงใน Google
Robin Hartmann

81

ด้วย Chrome, Firefox, Safari, Edge และ Webview คุณสามารถใช้ API การดึงข้อมูลซึ่งทำให้ง่ายขึ้นมาก

หากคุณต้องการการสนับสนุนสำหรับ IE หรือเบราว์เซอร์รุ่นเก่าคุณสามารถใช้การดึงข้อมูลโพลีฟิลได้

let url = 'https://example.com';

fetch(url)
.then(res => res.json())
.then((out) => {
  console.log('Checkout this JSON! ', out);
})
.catch(err => { throw err });

MDN: Fetch API

แม้ว่า Node.js ไม่มีเมธอดนี้อยู่ภายในคุณสามารถใช้การดึงข้อมูลโหนดซึ่งอนุญาตให้มีการนำไปปฏิบัติแบบเดียวกัน


6
อืม .. มันไม่ได้คอมไพล์ใน IE11 เหตุใด IE จึงเป็นขยะเช่นนี้
dano

4
คุณสามารถใช้ github / fetch polyfill เพื่อเอาชนะปัญหานี้ได้เสมอ
DBrown

@dano เป็นฟังก์ชั่นลูกศร ใช้ฟังก์ชั่นปกติหรือ Babel เพื่อ transpile
Phil

1
@Phil ขอบคุณสำหรับการชี้ให้เห็น ES6 ปัญหาที่ใหญ่ที่สุดของ IE11 คือการดึงข้อมูลไม่ใช่ API ที่รองรับ: developer.mozilla.org/en-US/docs/Web/API/Fetch_API นอกจากนี้ควรทราบว่าการดึงข้อมูล polyfill ที่จำเป็นสำหรับ IE11 นั้นเป็น ES5 อย่างแท้จริง (เนื่องจากไม่มี ของการสนับสนุน) ดังนั้นจึงไม่จำเป็นต้องใช้การถ่ายโอน ES6 เว้นแต่ว่าคุณต้องการมันเป็นอย่างอื่น หากเหตุผลเดียวที่จะเพิ่มมันคือการสนับสนุนสำนวนการดึงข้อมูล (ถ้าโพลีฟิลสนับสนุนแม้กระทั่ง) การใช้ babel-polyfill เป็นตัวเลือกที่ดีกว่า ขอให้โชคดี!
DBrown

8

ลอง ES8 (2017)

obj = await (await fetch(url)).json();

คุณสามารถจัดการข้อผิดพลาดด้วยการลองจับ


7

Axiosเป็นลูกค้า HTTP สัญญาที่ใช้สำหรับเบราว์เซอร์และ Node.js

มันมีการแปลงโดยอัตโนมัติสำหรับข้อมูล JSON และเป็นคำแนะนำอย่างเป็นทางการจากทีม Vue.jsเมื่อโอนย้ายจากเวอร์ชัน 1.0 ซึ่งรวมถึงไคลเอนต์ REST โดยค่าเริ่มต้น

ดำเนินการGETตามคำขอ

// Make a request for a user with a given ID
axios.get('http://query.yahooapis.com/v1/publ...')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

หรือแม้แต่axios(url)เพียงพอก็ต่อเมื่อGETคำขอเป็นค่าเริ่มต้น


3

กำหนดฟังก์ชั่นเช่น:

fetchRestaurants(callback) {
    fetch(`http://www.restaurants.com`)
       .then(response => response.json())
       .then(json => callback(null, json.restaurants))
       .catch(error => callback(error, null))
}

จากนั้นใช้แบบนี้:

fetchRestaurants((error, restaurants) => {
    if (error) 
        console.log(error)
    else 
        console.log(restaurants[0])

});

1
เนื่องจากมีคำตอบอยู่แล้วจำนวนมากโปรดพูดถึงสิ่งที่เกี่ยวกับคำตอบนี้ทำให้มูลค่าเพิ่มในการสนทนา มีการพูดถึงการใช้งานการดึงข้อมูลในคำตอบที่มีอยู่หลายข้อ
ToolmakerSteve

2
นี่เป็นคำตอบเดียวที่เกี่ยวข้องในปี 2020 เป็นเพียงการดึงข้อมูลที่ต้องการการติดต่อกลับเมื่อเหตุการณ์อะซิงโครนัสเสร็จสมบูรณ์ ง่ายและสง่างาม
lesolorzanov

เหตุใดจึงไม่fetchรอในกรณีนี้ ฉันสับสนฉันเห็นตัวอย่างที่รอคอยและถูกเรียกอย่างชัดเจน
Pynchia

0

เช้านี้ฉันยังมีข้อสงสัยเหมือนเดิมและตอนนี้ฉันได้ล้างมันใช้ JSON ด้วย 'open-weather-map' ( https://openweathermap.org/ ) api และรับข้อมูลจาก URL ในไฟล์ index.html รหัสมีลักษณะดังนี้: -

 //got location
 var x = document.getElementById("demo");
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(weatherdata);
      } else { 
        x.innerHTML = "Geolocation is not supported by this browser.";
      }
    //fetch openweather map url with api key
    function weatherdata(position) {
//put corrdinates to get weather data of that location
      fetch('https://api.openweathermap.org/data/2.5/weather?lat='+position.coords.latitude+'&lon='+position.coords.longitude+'&appid=b2c336bb5abf01acc0bbb8947211fbc6')
      .then(response => response.json())
      .then(data => {
      console.log(data);
      document.getElementById("demo").innerHTML = 
      '<br>wind speed:-'+data.wind.speed + 
      '<br>humidity :-'+data.main.humidity + 
      '<br>temprature :-'+data.main.temp  
      });
    }
  <div id="demo"></div>

ฉันให้รหัส api อย่างเปิดเผยเพราะฉันมีการสมัครฟรีเพียงแค่สมัครสมาชิกฟรีในตอนแรก คุณสามารถหารหัส API และคีย์ฟรีที่ "rapidapi.com"


-1

คุณสามารถเข้าถึงข้อมูล JSON โดยใช้ fetch () ใน JavaScript

อัปเดตพารามิเตอร์ url ของการดึงข้อมูล () ด้วย url ของคุณ

fetch(url)
    .then(function(response){
        return response.json();
    })
    .then(function(data){
        console.log(data);
    })

หวังว่ามันจะช่วยให้มันทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน


2
เรื่องนี้ดูเหมือนจะซ้ำกับคำตอบของ DBrown โปรดอย่าเพิ่มคำตอบที่ซ้ำกัน หากมีบางอย่างที่ไม่ซ้ำกันเกี่ยวกับคำตอบนี้ให้พูดถึงคำตอบของ DBrown และอธิบายสิ่งที่แตกต่างเกี่ยวกับคุณ
ToolmakerSteve

-1
//Resolved
const fetchPromise1 = fetch(url);
    fetchPromise1.then(response => {
      console.log(response);
    });


//Pending
const fetchPromise = fetch(url);
console.log(fetchPromise);

1
นี่คือรหัสคำตอบเท่านั้น! เพิ่มคำอธิบายบางอย่างให้กับโพสต์
Ram Ghadiyaram

2
เนื่องจากมีคำตอบอยู่แล้วจำนวนมากโปรดพูดถึงสิ่งที่เกี่ยวกับคำตอบนี้ทำให้มูลค่าเพิ่มในการสนทนา fetchมีการกล่าวถึงการใช้งานในคำตอบที่มีอยู่หลายข้อ
ToolmakerSteve

-1

async function fetchDataAsync() {
    const response = await fetch('paste URL');
    console.log(await response.json())

}


fetchDataAsync();


โปรดอธิบายบางสิ่งเกี่ยวกับคำตอบของคุณ
Angel F Syrus

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