我正在查看以下API:
http://wiki.github.com/soundcloud/api/oembed-api
他们给出的例子是
呼叫:
http://soundcloud.com/oembed?url=http%3A//soundcloud.com/forss/flickermood&format=json
响应:
{
"html":"<object height=\"81\" ... ",
"user":"Forss",
"permalink":"http:\/\/soundcloud.com\/forss\/flickermood",
"title":"Flickermood",
"type":"rich",
"provider_url":"http:\/\/soundcloud.com",
"description":"From the Soulhack album...",
"version":1.0,
"user_permalink_url":"http:\/\/soundcloud.com\/forss",
"height":81,
"provider_name":"Soundcloud",
"width":0
}
如何从网址获取此JSON对象,我该怎么做?
答案 0 :(得分:57)
它们似乎为format参数提供了js
选项,它将返回JSONP。您可以像这样检索JSONP:
function getJSONP(url, success) {
var ud = '_' + +new Date,
script = document.createElement('script'),
head = document.getElementsByTagName('head')[0]
|| document.documentElement;
window[ud] = function(data) {
head.removeChild(script);
success && success(data);
};
script.src = url.replace('callback=?', 'callback=' + ud);
head.appendChild(script);
}
getJSONP('http://soundcloud.com/oembed?url=http%3A//soundcloud.com/forss/flickermood&format=js&callback=?', function(data){
console.log(data);
});
答案 1 :(得分:46)
标准的http GET请求应该这样做。然后,您可以使用JSON.parse()将其转换为json对象。
function Get(yourUrl){
var Httpreq = new XMLHttpRequest(); // a new request
Httpreq.open("GET",yourUrl,false);
Httpreq.send(null);
return Httpreq.responseText;
}
然后
var json_obj = JSON.parse(Get(yourUrl));
console.log("this is the author name: "+json_obj.author_name);
基本上它
答案 2 :(得分:11)
由于该网址与您的网站不在同一个域中,因此您需要使用JSONP。
例如:(在jQuery中):
$.getJSON(
'http://soundcloud.com/oembed?url=http%3A//soundcloud.com/forss/flickermood&format=js&callback=?',
function(data) { ... }
);
这可以通过创建像这样的<script>
标签来实现:
<script src="http://soundcloud.com/oembed?url=http%3A//soundcloud.com/forss/flickermood&format=js&callback=someFunction" type="text/javascript"></script>
然后他们的服务器会发出调用someFunction
的Javascript以及要检索的数据
`someFunction是由jQuery生成的内部回调,然后调用你的回调。
答案 3 :(得分:7)
DickFeynman的答案是一个可行的解决方案,适用于任何JQuery不适合或不需要的情况。正如ComFreek所说,这需要在服务器端设置CORS头。如果它是您的服务,并且您可以处理更大的安全问题,那么这完全可行。
这里列出了Flask服务,设置CORS标头,从数据库中获取数据,使用JSON进行响应,以及在客户端使用DickFeynman的方法快乐地工作:
#!/usr/bin/env python
from __future__ import unicode_literals
from flask import Flask, Response, jsonify, redirect, request, url_for
from your_model import *
import os
try:
import simplejson as json;
except ImportError:
import json
try:
from flask.ext.cors import *
except:
from flask_cors import *
app = Flask(__name__)
@app.before_request
def before_request():
try:
# Provided by an object in your_model
app.session = SessionManager.connect()
except:
print "Database connection failed."
@app.teardown_request
def shutdown_session(exception=None):
app.session.close()
# A route with a CORS header, to enable your javascript client to access
# JSON created from a database query.
@app.route('/whatever-data/', methods=['GET', 'OPTIONS'])
@cross_origin(headers=['Content-Type'])
def json_data():
whatever_list = []
results_json = None
try:
# Use SQL Alchemy to select all Whatevers, WHERE size > 0.
whatevers = app.session.query(Whatever).filter(Whatever.size > 0).all()
if whatevers and len(whatevers) > 0:
for whatever in whatevers:
# Each whatever is able to return a serialized version of itself.
# Refer to your_model.
whatever_list.append(whatever.serialize())
# Convert a list to JSON.
results_json = json.dumps(whatever_list)
except SQLAlchemyError as e:
print 'Error {0}'.format(e)
exit(0)
if len(whatevers) < 1 or not results_json:
exit(0)
else:
# Because we used json.dumps(), rather than jsonify(),
# we need to create a Flask Response object, here.
return Response(response=str(results_json), mimetype='application/json')
if __name__ == '__main__':
#@NOTE Not suitable for production. As configured,
# your Flask service is in debug mode and publicly accessible.
app.run(debug=True, host='0.0.0.0', port=5001) # http://localhost:5001/
your_model包含任何内容的序列化方法,以及数据库连接管理器(可以进行一些重构,但足以在较大的系统或模型/视图/控制体系结构中集中创建数据库会话)。这恰好使用postgreSQL,但可以轻松使用任何服务器端数据存储:
#!/usr/bin/env python
# Filename: your_model.py
import time
import psycopg2
import psycopg2.pool
import psycopg2.extras
from psycopg2.extensions import adapt, register_adapter, AsIs
from sqlalchemy import update
from sqlalchemy.orm import *
from sqlalchemy.exc import *
from sqlalchemy.dialects import postgresql
from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
class SessionManager(object):
@staticmethod
def connect():
engine = create_engine('postgresql://id:passwd@localhost/mydatabase',
echo = True)
Session = sessionmaker(bind = engine,
autoflush = True,
expire_on_commit = False,
autocommit = False)
session = Session()
return session
@staticmethod
def declareBase():
engine = create_engine('postgresql://id:passwd@localhost/mydatabase', echo=True)
whatever_metadata = MetaData(engine, schema ='public')
Base = declarative_base(metadata=whatever_metadata)
return Base
Base = SessionManager.declareBase()
class Whatever(Base):
"""Create, supply information about, and manage the state of one or more whatever.
"""
__tablename__ = 'whatever'
id = Column(Integer, primary_key=True)
whatever_digest = Column(VARCHAR, unique=True)
best_name = Column(VARCHAR, nullable = True)
whatever_timestamp = Column(BigInteger, default = time.time())
whatever_raw = Column(Numeric(precision = 1000, scale = 0), default = 0.0)
whatever_label = Column(postgresql.VARCHAR, nullable = True)
size = Column(BigInteger, default = 0)
def __init__(self,
whatever_digest = '',
best_name = '',
whatever_timestamp = 0,
whatever_raw = 0,
whatever_label = '',
size = 0):
self.whatever_digest = whatever_digest
self.best_name = best_name
self.whatever_timestamp = whatever_timestamp
self.whatever_raw = whatever_raw
self.whatever_label = whatever_label
# Serialize one way or another, just handle appropriately in the client.
def serialize(self):
return {
'best_name' :self.best_name,
'whatever_label':self.whatever_label,
'size' :self.size,
}
回想起来,我可能已将所有对象序列化为列表,而不是Python dict,这可能简化了他们在Flask服务中的处理,我可能在Flask实现中更好地分离了关注点(数据库调用可能不应该& #39;内置在路由处理程序中),但是,只要您在自己的开发环境中拥有可用的解决方案,您就可以改进这一点。
另外,我并不是建议人们避免使用JQuery。但是,如果JQuery不在图片中,出于某种原因,这种方法似乎是一种合理的选择。
无论如何,它都有效。这是我在客户端实施DickFeynman的方法:
<script type="text/javascript">
var addr = "dev.yourserver.yourorg.tld"
var port = "5001"
function Get(whateverUrl){
var Httpreq = new XMLHttpRequest(); // a new request
Httpreq.open("GET",whateverUrl,false);
Httpreq.send(null);
return Httpreq.responseText;
}
var whatever_list_obj = JSON.parse(Get("http://" + addr + ":" + port + "/whatever-data/"));
whatever_qty = whatever_list_obj.length;
for (var i = 0; i < whatever_qty; i++) {
console.log(whatever_list_obj[i].best_name);
}
</script>
我不会列出我的控制台输出,但我正在查看一长串的whatever.best_name字符串。
更重要的是:whatever_list_obj可以在我的javascript命名空间中使用,我关心的任何,...可能包括用D3.js生成图形,映射到OpenLayers或CesiumJS,或计算一些不需要特别需要在我的DOM中生存的中间值。
答案 4 :(得分:6)
在现代JS中,您可以通过在URL上调用ES6的fetch()
,然后使用ES7的async/await
来将Response对象从提取到像这样获取JSON数据:
const getJSON = async url => {
try {
const response = await fetch(url);
if(!response.ok) // check if response worked (no 404 errors etc...)
throw new Error(response.statusText);
const data = await response.json(); // get JSON from the response
return data; // returns a promise, which resolves to this data value
} catch(error) {
return error;
}
}
console.log("Fetching data...");
getJSON("https://soundcloud.com/oembed?url=http%3A//soundcloud.com/forss/flickermood&format=json").then(data => {
console.log(data);
}).catch(error => {
console.error(error);
});
如果忽略异常/错误处理,通常可以将上述方法简化为几行(通常不建议这样做,因为这会导致不必要的错误):
const getJSON = async url => {
const response = await fetch(url);
return response.json(); // get JSON from the response
}
console.log("Fetching data...");
getJSON("https://soundcloud.com/oembed?url=http%3A//soundcloud.com/forss/flickermood&format=json")
.then(data => console.log(data));
答案 5 :(得分:4)
您制作了标准的HTTP GET请求。您将获得一个标准的HTTP响应,其中包含application / json内容类型和JSON文档作为正文。然后你解析它。
由于您已标记此“JavaScript”(我假设您的意思是“来自浏览器中的网页”),并且我认为这是第三方服务,因此您会被卡住。除非设置了明确的解决方法(例如JSONP),否则无法在JavaScript中从远程URI获取数据。
哦等等,阅读你链接到的文档 - JSONP可用,但你必须说'js'而不是'json'并指定一个回调:format = js&amp; callback = foo
然后你可以定义回调函数:
function foo(myData) {
// do stuff with myData
}
然后加载数据:
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = theUrlForTheApi;
document.body.appendChild(script);