Skip to main content

Usando CORS e JSONP para fazer solicitações de origem cruzada

Você pode fazer solicitações de API entre domínios usando compartilhamento de recursos entre origens (CORS) e retornos de chamada JSONP.

Sobre as solicitações entre origens

Uma solicitação entre origens é uma solicitação feita a um domínio diferente do que originou a solicitação. Por motivos de segurança, a maioria dos navegadores da Web bloqueia solicitações entre origens. No entanto, você pode usar o compartilhamento de recursos entre origens (CORS) e retornos de chamada JSONP para fazer solicitações entre origens.

Compartilhamento de recursos entre origens (CORS)

A API REST é compatível com o compartilhamento de recurso entre origens (CORS) para solicitações AJAX de qualquer origem. Para obter mais informações, confira a Recomendação do W3C para CORS e o Guia de Segurança do HTML 5

Aqui está uma solicitação de exemplo enviada de um navegador atingindo http://example.com:

$ curl -I https://api.github.com -H "Origin: http://example.com"
HTTP/2 302
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: ETag, Link, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval

A solicitação pré-voo de CORS se parece com isso:

$ curl -I https://api.github.com -H "Origin: http://example.com" -X OPTIONS
HTTP/2 204
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With
Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE
Access-Control-Expose-Headers: ETag, Link, x-ratelimit-limit, x-ratelimit-remaining, x-ratelimit-reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
Access-Control-Max-Age: 86400

Chamadas de retorno do JSON-P

Você pode enviar um parâmetro ?callback para qualquer chamada de GET para envolver os resultados em uma função JSON. Em geral, isso é usado quando os navegadores desejam incorporar o conteúdo do GitHub em páginas da Web e evitar problemas entre domínios. A resposta inclui a mesma saída de dados da API regular, mais as informações relevantes do cabeçalho de HTTP.

$ curl https://api.github.com?callback=foo

> /**/foo({
>   "meta": {
>     "status": 200,
>     "x-ratelimit-limit": "5000",
>     "x-ratelimit-remaining": "4966",
>     "x-ratelimit-reset": "1372700873",
>     "Link": [ // pagination headers and other links
>       ["https://api.github.com?page=2", {"rel": "next"}]
>     ]
>   },
>   "data": {
>     // the data
>   }
> })

Você pode escrever um manipulador do JavaScript para processar o retorno de chamada. Aqui está um exemplo pequeno que você pode testar:

<html>
<head>
<script type="text/javascript">
function foo(response) {
  var meta = response.meta;
  var data = response.data;
  console.log(meta);
  console.log(data);
}

var script = document.createElement('script');
script.src = 'https://api.github.com?callback=foo';

document.getElementsByTagName('head')[0].appendChild(script);
</script>
</head>

<body>
  <p>Open up your browser's console.</p>
</body>
</html>

Todos os cabeçalhos têm o mesmo valor da sequência que os cabeçalhos HTTP, exceto Link. Cabeçalhos Link são pré-analisados para você e chegam como uma matriz de tuplas [url, options].

Por exemplo, um link parecido com este:

Link: <url1>; rel="next", <url2>; rel="foo"; bar="baz"

será mostrado assim na saída do retorno de chamada:

{
  "Link": [
    [
      "url1",
      {
        "rel": "next"
      }
    ],
    [
      "url2",
      {
        "rel": "foo",
        "bar": "baz"
      }
    ]
  ]
}