XMLHttpRequest não pode carregar uma URL com jQuery

Estou tentando obter alguns dados json de um site “remoto”. Eu executo meu serviço da web na porta 99000 e, em seguida, inicio meu site na porta 99001 (http: // localhost: 99001 / index.html).

Eu recebo a seguinte mensagem:

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

Mesmo se eu lançar minha página da web como um arquivo HTML, eu recebo isso:

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

O serviço da web retorna dados. Eu tento pegar os itens de dados como este:

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

E estou tentando obter essa estrutura:

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

Você sabe porque estou recebendo esse erro?

   

Você não pode fazer um crossdomain XMLHttpRequest, a única “opção” seria uma técnica chamada JSONP, que se resume a isto:

Para iniciar a solicitação: Adicione uma nova tag ao url remoto e verifique se a url remota retorna um arquivo javascript válido que chama sua function de retorno de chamada. Alguns serviços suportam isso (e permitem nomear seu retorno de chamada em um parâmetro GET).

A outra maneira fácil, seria criar um "proxy" no seu servidor local, que recebe o pedido remoto e, em seguida, apenas "encaminha" de volta para o seu javascript.

editar / adição:

Eu vejo jQuery tem suporte embutido para JSONP, verificando se o URL contém "callback =?" (onde jQuery irá replace? com o método de callback real). Mas você ainda precisa processar isso no servidor remoto para gerar uma resposta válida.

No novo jQuery 1.5 você pode 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); } }) 

Mexa com 3 soluções de trabalho em ação.

Dado um 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' 

Solução 1: $ .ajax () + jsonp:

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

Solução 2: $ .ajax () + json + & calback = ?:

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

Solução 3: $ .getJSON () + calback = ?:

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

Documentações: http://api.jquery.com/jQuery.ajax/ , http://api.jquery.com/jQuery.getJSON/

Encontrei uma possível solução alternativa que não acredito que foi mencionada.

Aqui está uma boa descrição do problema: http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

Basicamente, desde que você use os tipos de conteúdo forms / url-encoded / plain text você está bem.

 $.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)); } }); 

Eu uso com ASP.NET WebAPI2. Então, do outro lado:

 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")); } 

Desta forma, o formatador Json é usado ao analisar o tipo de conteúdo de texto simples.

E não esqueça no Web.config:

        

Espero que isto ajude.

Estou usando o WebAPI 3 e estava enfrentando o mesmo problema. O problema foi resolvido quando @Rytis adicionou sua solução. E acho que no WebAPI 3, não precisamos definir o método RegisterWebApi .

Minha mudança foi apenas no arquivo web.config e está funcionando.

       

Obrigado pela sua solução @Rytis!