Isto é o documento histórico que deu origem a este domínio, preservado como estava. Voltar pro blog em json-p.org.

DocumentoProposta JSON-P original AutorBob Ippolito PublicadoDezembro de 2005 Preservado emjson-p.org Nota: este texto foi traduzido para o português e é mantido aqui como referência histórica. A técnica descrita foi majoritariamente substituída por CORS.

Json-P

Ajax entre domínios antes do CORS

// `data` agora é a representação do objeto dos dados JSON
função handle_data(data) {
  // ...
}

--- requisição ---
http://algum.dominio/servico?callback=handle_data

--- resposta ---
handle_data({"dado_1": "olá mundo", "dado_2": ["the", "sun", "is", "shining"]});
§1

O que é JSON

JSON é um formato leve de intercâmbio de dados. Foi formalmente padronizado por Douglas Crockford e, desde então, foi recebido quase universalmente como uma representação simples e poderosa de dados para transmissão entre duas entidades, independentemente da linguagem de computador em que essas entidades são executadas nativamente.

§2

Ajax entre domínios: breve introdução

A política de mesma origem nos navegadores determina que certos tipos de transferência de dados na camada do navegador (via JavaScript) devem ser restritos a ocorrer apenas se o domínio do recurso de destino for idêntico ao da página que faz a solicitação. Essa política está em vigor em todos os navegadores modernos para proteger os usuários contra comportamentos JavaScript maliciosos ou inseguros.

Ajax entre domínios refere-se à ideia de fazer solicitações entre domínios em oposição a essa restrição. Isso não é inerentemente inseguro, é de fato essencial para muitos dos mashups mais populares e úteis da web. Mas o Ajax entre domínios feito corretamente procura usar técnicas que, por várias razões, não estejam sujeitas à política de mesma origem.

§3

JSON-P (JSONP)

Um dos mecanismos que podem solicitar conteúdo entre domínios é a tag <script>. Em dezembro de 2005, Bob Ippolito propôs formalmente o JSONP (depois chamado de JSON-P) como uma maneira de aproveitar essa propriedade para solicitar dados no formato JSON entre domínios.

O JSON-P funciona criando um elemento <script> que solicita um recurso remoto. A resposta é o nome de uma função predefinida na página solicitante, com o parâmetro sendo os dados JSON pedidos. Quando o script é executado, a função é chamada e recebe os dados, permitindo que a página solicitante os processe.

Como se pode ver no exemplo acima, o serviço remoto sabia qual função chamar com base no nome indicado na URL da solicitação. Desde que essa função esteja de fato definida na página solicitante, ela será chamada e receberá os dados pedidos.

§4

O problema

Até então, o JSON-P era essencialmente uma convenção flexível, quando na realidade o navegador aceita qualquer JavaScript arbitrário na resposta. Isso significa que quem confia no JSON-P para Ajax entre domínios está, de fato, se abrindo ao mesmo tipo de risco que a política de mesma origem tentava evitar. Um serviço malicioso pode retornar a chamada de função esperada, mas incluir junto outra lógica JavaScript que corrompe a página ou envia dados privados do usuário para fora.

Por essa razão, o JSON-P é visto por muitos como uma abordagem insegura para Ajax entre domínios. Quem o usa deve ser criterioso, fazendo chamadas apenas a serviços remotos que controla ou em que confia implicitamente.

§5

Alternativas

Existem várias alternativas ao JSON-P, cada uma com seus próprios desafios. Vale destacar uma: o CORS (Compartilhamento de Recursos entre Origens), extensão do XMLHttpRequest que permite ao navegador fazer chamadas entre domínios pré-confirmando a solicitação com o servidor de destino, que pode então autorizar ou recusar.

O servidor remoto pode expor conteúdo apenas a uma lista predefinida de domínios aprovados, ou abrir para qualquer origem, se achar conveniente. À primeira vista o CORS parece a solução ideal, tornando o JSON-P obsoleto. Mas ele exige lógica não trivial no servidor para lidar com cabeçalhos de solicitação e requisições de "preflight", o que torna a adoção mais lenta do que a simplicidade do JSON-P.

§6

A solução proposta

Por enquanto, o JSON-P segue viável para Ajax entre domínios, provavelmente lado a lado com o CORS, para atender navegadores e serviços que ainda não suportam esse último. Era necessária, no entanto, uma definição de subconjunto mais rigorosa para o que deveria ser considerado JSON-P válido e seguro:

nome_da_funcao({JSON}); obj.nomeDaFuncao({JSON}); obj["nome da função"]({JSON});

A intenção é que apenas uma única expressão de referência de função seja usada como "padding" da resposta, seguida imediatamente por um único par de parênteses envolvendo um objeto JSON estritamente válido. Nenhum outro conteúdo, além de espaço em branco ou comentários válidos de JavaScript, deveria aparecer na resposta.

A parte mais crítica da proposta é que os fornecedores de navegadores comecem a aplicar essa regra às tags de script que recebem conteúdo JSON-P, gerando erros para qualquer conteúdo fora do padrão.

§7

Desvantagens

Navegadores que não suportam CORS provavelmente também não seriam atualizados para aplicar essa filtragem estrita do JSON-P, deixando seus usuários sem essa proteção adicional. Ainda assim, todos os navegadores atuais poderiam adicionar suporte à filtragem, tornando o JSON-P mais seguro para quem consome serviços que ainda não suportam CORS.

§8

Nota

Uma técnica de mitigação para navegadores mais antigos seria o autor detectar a ausência desse suporte e direcionar essas solicitações através de um proxy local ou de um proxy do lado do cliente, que atuaria como gateway aplicando a filtragem de conteúdo descrita acima.

§9

Caso de uso alternativo: teste de unidade

Outro caso de uso interessante para um padrão de JSON-P é poder testar APIs de unidade que produzem saída JSON-P. Isso já é comum para APIs JSON puras, mas para APIs JSON-P não havia uma boa forma de validar a saída por um analisador.

§10

Avançando

Esta foi uma primeira passagem dessa definição para um JSON-P mais seguro, aberta à comunidade em geral para avaliar prós e contras e colaborar em uma definição viável que pudesse ser defendida junto aos fornecedores de navegadores.