XMLHttpRequest no puede cargar una URL con jQuery

5 minutos de lectura

XMLHttpRequest no puede cargar una URL con jQuery
Zakaria

Estoy tratando de obtener algunos datos json de un sitio web “remoto”. Ejecuto mi servicio web en el puerto 99000 y luego lanzo mi sitio web en el puerto 99001 (http://localhost:99001/index.html).

Recibo el siguiente mensaje:

    XMLHttpRequest cannot load http://localhost:99000/Services.svc/ReturnPersons. Origin http://localhost:99001 is not allowed by Access-Control-Allow-Origin.

Incluso si abro mi página web como un archivo HTML, obtengo esto:

    XMLHttpRequest cannot load http://localhost:99000/Services.svc/ReturnPersons.Origin null is not allowed by Access-Control-Allow-Origin.

El servicio web devuelve datos. Intento capturar los elementos de datos como este:

var url = "http://localhost:99000/Services.svc/ReturnPersons";
$.getJSON(url, function (data) {
success: readData(data)
});
function readData(data) {
    alert(data[0].FirstName);
}

Y estoy tratando de obtener esta estructura:

[{"FirstName":"Foo","LastName":"Bar"},{"Hello":"Foo","LastName":"World"}]

¿Sabes por qué me sale este error?

XMLHttpRequest no puede cargar una URL con jQuery
charleshoja

No puede hacer un dominio cruzado XMLHttpRequest, la única “opción” sería una técnica llamada JSONP, que se reduce a esto:

Para iniciar la solicitud: Agregar un nuevo <script> etiqueta con la URL remota y luego asegúrese de que la URL remota devuelva un archivo javascript válido que llame a su función de devolución de llamada. Algunos servicios admiten esto (y le permiten nombrar su devolución de llamada en parámetros GET).

La otra salida fácil sería crear un “proxy” en su servidor local, que recibe la solicitud remota y luego simplemente la “reenvía” a su javascript.

editar/añadir:

Veo que jQuery tiene soporte incorporado para JSONP, comprobando si la URL contiene “callback=?” (donde jQuery reemplazará? con el método de devolución de llamada real). Pero aún necesitaría procesar eso en el servidor remoto para generar una respuesta válida.

  • Resolví el problema agregando “&callback=?” a la URL. ¡Gracias!

    – Zakaria

    30 de septiembre de 2010 a las 9:58

  • ¿Tengo que especificar/implementar algo en el script del servidor en el servidor remoto?

    – j7nn7k

    1 de agosto de 2011 a las 13:49

  • Sí, donde su servidor normalmente devuelve una cadena JSON, por ejemplo {"foo": "bar"} necesita envolver la cadena json en un método de devolución de llamada (función javascript) que maneja la respuesta json. p.ej myFunction({"foo": "bar"});

    – CharlesLeaf

    2 de agosto de 2011 a las 12:36

  • Charles Leaf, en realidad estás equivocado. Hay otra “opción” que se llama CORS. Comprueba cómo habilitarlo aquí: enable-cors.org

    – Benathon

    23/09/2012 a las 23:30

  • Tienes razón portforwardpodcast, pero cuando esta pregunta se hizo originalmente en 2010, CORS era una opción menos popular (para ser justos: una de la que nunca había oído hablar en ese entonces) y aunque la mayoría ha eliminado el soporte de IE6, todavía hay una demanda para admitir IE7 que no admite CORS e IE8 solo lo admite parcialmente. Entonces, dependiendo de sus requisitos, esta es una opción muy válida (y mejor), sí.

    – CharlesLeaf

    8 de diciembre de 2012 a las 7:03

En el nuevo jQuery 1.5 puedes usar:

$.ajax({
    type: "GET",
    url: "http://localhost:99000/Services.svc/ReturnPersons",
    dataType: "jsonp",
    success: readData(data),
    error: function (xhr, ajaxOptions, thrownError) {
      alert(xhr.status);
      alert(thrownError);
    }
})

  • supongo que es extra “:” en tu respuesta. ¿Podrías pegar el mensaje completo?

    – Eslavo

    24 de julio de 2015 a las 3:20

XMLHttpRequest no puede cargar una URL con jQuery
Hugolpz

Juega con 3 soluciones de trabajo en acción.

Dado un JSON externo:

myurl="http://wikidata.org/w/api.php?action=wbgetentities&sites=frwiki&titles=France&languages=zh-hans|zh-hant|fr&props=sitelinks|labels|aliases|descriptions&format=json"

Solución 1: $.ajax() + jsonp:

$.ajax({
  dataType: "jsonp",
  url: myurl ,
  }).done(function ( data ) {
  // do my stuff
});

Solución 2: $.ajax()+json+&calback=?:

$.ajax({
  dataType: "json",
  url: myurl + '&callback=?',
  }).done(function ( data ) {
  // do my stuff
});

Solución 3: $.getJSON()+calback=?:

$.getJSON( myurl + '&callback=?', function(data) {
  // do my stuff
});

Documentaciones: http://api.jquery.com/jQuery.ajax/ , http://api.jquery.com/jQuery.getJSON/

  • JSfiddle se corrigió después de los cambios en la API de #wikidata, se completó la mejora de jsfiddle, se completó la mejora de la redacción.

    – Hugolpz

    24/10/2013 a las 14:21


  • @TuhinPaul: cuando estás en https violín que no puedes solicitar http wikidata u otros http, sería una brecha de seguridad. Puede hacer http-http, https-https o http-https, no https-http. Esta es una función de seguridad, no un problema entre dominios.

    – Hugolpz

    7 dic 2016 a las 15:47


Encontré una posible solución que no creo que se haya mencionado.

Aquí hay una buena descripción del problema:
http://www.asp.net/web-api/overview/security/habilitación-cross-origin-requests-in-web-api

Básicamente, siempre que use formularios/codificados en URL/tipos de contenido de texto sin formato, estará bien.

$.ajax({
    type: "POST",
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'text/plain'
    },
    dataType: "json",
    url: "http://localhost/endpoint",
    data: JSON.stringify({'DataToPost': 123}),
    success: function (data) {
        alert(JSON.stringify(data));
    }
});     

Lo uso con ASP.NET WebAPI2. Entonces, en el otro extremo:

public static void RegisterWebApi(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();

    config.Formatters.Clear();
    config.Formatters.Add(new JsonMediaTypeFormatter());

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain"));
}

De esta forma, el formateador Json se utiliza al analizar el tipo de contenido de texto sin formato.

Y no olvides en Web.config:

<system.webServer>
<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET, POST" />
  </customHeaders>
</httpProtocol>    

Espero que esto ayude.

XMLHttpRequest no puede cargar una URL con jQuery
navin pandit

Estoy usando WebAPI 3 y estaba enfrentando el mismo problema. El problema se resolvió ya que @Rytis agregó su solución. Y creo que en WebAPI 3, no necesitamos definir el método RegisterWebApi.

Mi cambio fue solo en el archivo web.config y está funcionando.

<httpProtocol>
 <customHeaders>
 <add name="Access-Control-Allow-Origin" value="*" />
 <add name="Access-Control-Allow-Methods" value="GET, POST" />
</customHeaders>
</httpProtocol> 

¡Gracias por tu solución @Rytis!

¿Ha sido útil esta solución?