respuesta de DickFeynman es una solución viable para cualquier circunstancia en la que jQuery no es un buen ajuste, o no se indique lo contrario. Como señala ComFreek, esto requiere configurar los encabezados CORS en el lado del servidor.Si es su servicio, y tiene un control sobre la gran cuestión de la seguridad, entonces eso es totalmente factible.
Aquí hay una lista de un servicio Frasco, el establecimiento de los encabezados CORS, tomando datos de una base de datos, respondiendo con JSON, y trabajar felizmente con el enfoque de DickFeynman en el lado del cliente:
#!/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 contiene la serialización método para lo que sea, así como el administrador de conexión de base de datos (que podría soportar una pequeña refactorización, pero es suficiente para centralizar la creación de sesiones de base de datos, en sistemas más grandes o arquitecturas Modelo/Vista/Control). Esto sucede a usar PostgreSQL, pero sólo podía utilizar la misma facilidad cualquier almacén de datos del lado del servidor:
#!/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:[email protected]/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:[email protected]/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,
}
En retrospectiva, podría haber serializado los cualesquiera que sean los objetos como listas, en lugar de un diccionario de Python, que podría haber simplificado su procesamiento en el servicio Flask, y podría haber separado las preocupaciones en la implementación de Flask (la llamada a la base de datos probablemente no debería estar incorporada en el controlador de ruta), pero usted puede mejorar esto, una vez que tenga una solución de trabajo en su propio entorno de desarrollo.
Además, no estoy sugiriendo que la gente evite JQuery. Pero, si JQuery no está en la imagen, por una razón u otra, este enfoque parece una alternativa razonable.
Funciona, en cualquier caso.
Aquí está mi aplicación del enfoque de DickFeynman, en el que el cliente:
<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>
que no voy a enumerar mi salida de la consola, pero estoy buscando a una larga lista de cadenas whatever.best_name.
Más al punto: La whatever_list_obj está disponible para su uso en mi espacio de nombres Javascript, por lo me importa que ver con eso, ... que pueden incluir gráficos generadores con D3.js, mapeo con OpenLayers o CesiumJS, o calculando algunos valores intermedios que no tienen ninguna necesidad particular de vivir en mi DOM.
esto funciona perfectamente, gracias J-P! interesante que los métodos jquery no parecían funcionar ... – Haroldo
¿este método getJSONP funciona para un objeto json sin la fila html? – Lisa
Esta respuesta me sorprendió al principio ya que el título del post es JSON, y no me di cuenta de inmediato que este ejemplo de código devuelve JSONP, que no es JSON en absoluto (y por lo tanto no leería correctamente el formato JSON) La respuesta a continuación de @DickFeynman se debe superar por encima de esta, funciona perfectamente. Aquí hay un tutorial que muestra las diferencias entre JSON y JSONP: https://web.archive.org/web/20160114013014/http://json-jsonp-tutorial.craic.com/index.html – ashleedawg