Sinatra, JavaScript Cross Domain Solicita JSON
-
22-09-2019 - |
Pergunta
Eu corro um API de descanso em cima de Sinatra. Agora eu quero escrever um script jQuery que busque dados da API.
Sinatra é instruído a responder com JSON
before do
content_type :json
end
Uma rota simples parece
get '/posts' do
Post.find.to_json
end
Meu script jQuery é um Ajax-call simples
$.ajax({
type: 'get',
url: 'http://api.com/posts',
dataType: 'json',
success: function(data) {
// do something
}
})
Na verdade, tudo funciona bem, desde que ambos sejam executados no mesmo IP, API e solicitando JS. Eu já tentei brincar com o JSONP para rack sem resultados positivos. Provavelmente eu só preciso de uma dica de como proceder.
Solução
Usar JSONP (JSON com estofamento). Existe um Extensão JSONP para rack.
Basicamente, você ligará:
$.ajax({
type: 'get',
url: 'http://api.com/posts',
dataType: 'jsonp',
success: function(data) {
// do something
}
})
que se traduz em um pedido como:
http://api.com/posts?callback=someJSFunc
E seu servidor responderá, por exemplo:
someJSFunc({"json":"obj"});
Obviamente, os clientes podem fazer solicitações JSONP sem jQuery. O truque com o JSONP é que você serve scripts, que podem ser domínios cruzados, em vez de JSON puro, com não pode.
Outras dicas
Obrigado pelas respostas até agora. Você estava certo e o JSONP resolveria o problema. Os trechos de código para JavaScript funcionam bem. Configurar Sinatra é muito fácil, pois é construído em cima do rack. Portanto, basta instalar a jóia do rack-contrrible
gem install rack-rack-contrib --source=http://gems.github.com/
(ou coloque -o no seu gemfile) e adicione
require 'rack/contrib/jsonp'
use Rack::JSONP
para o seu aplicativo.
Este middleware fornece clientes JSON regulares a JSONP e JSONP para a JQuery & Co.
Pode ser interessante para você http://github.com/shtirlic/sinatra-jsonp - Esta extensão adiciona funcionalidade ausente a Sinatra
Também disponível como gem gem install sinatra-jsonp
Tente ligar
$.getJSON("http://example.com/?callback=?",function(data) { alert(data); });
Nesta amostra, a palavra-chave principal é a construção de "retorno de chamada =?", Então você precisa processar esse parâmetro no seu script do lado do servidor e fazer um JSONP válido, como este:
function({ "foo" : "bar" });
Onde "função" são dados aleatórios, que são gerados pelo jQuery automaticamente. Consulte Mais informação aqui Sobre JQuery e JSONP de domínio cruzado.