Skip to main content

Uso de CORS y JSONP para realizar solicitudes entre orígenes

Puedes realizar solicitudes de API entre dominios mediante el Intercambio de recursos de origen cruzado (CORS) y devoluciones de llamada JSONP.

Acerca de las solicitudes de origen cruzado

Una solicitud entre orígenes es una solicitud realizada a un dominio diferente al que origina la solicitud. Por motivos de seguridad, la mayoría de los exploradores web bloquean las solicitudes entre orígenes. Sin embargo, puedes utilizar el Intercambio de recursos de origen cruzado (CORS) y devoluciones de llamada JSONP para realizar solicitudes entre orígenes.

Uso compartido de recursos entre orígenes (CORS)

La API de REST es compatible con el Intercambio de recursos de origen cruzado (CORS) para las solicitudes AJAX desde cualquier origen. Para obtener más información, consulta la «Recomendación de W3C CORS» y la Guía de seguridad de HTML 5

Esta es una solicitud de ejemplo enviada desde un explorador destinada a 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

Así se ve una solicitud de prevuelo de CORS:

$ 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

Rellamados de JSON-P

Puede enviar un parámetro ?callback a cualquier llamada GET para que los resultados se encapsulen en una función JSON. Esto se suele usar cuando los exploradores quieren insertar contenido de GitHub en páginas web y evitar los problemas de dominios cruzados. La respuesta incluye la misma salida de datos que la API común, además de la información pertinente del encabezado 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
>   }
> })

Puedes escribir un agente de JavaScript para procesar la rellamada. Aquí hay un ejemplo minimalista que puedes probar:

<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 los encabezados tienen el mismo valor de cadena que los encabezados HTTP, salvo Link. Los encabezados Link se analizan previamente de forma automática y se pasan como una matriz de tuplas [url, options].

Por ejemplo, un enlace que se ve así:

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

se verá así en la salida de la rellamada:

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