Pergunta

Estou tentando obter alguns dados JSON de um site "remoto". Eu executo meu serviço da web na porta 99000, então inicio meu site na porta 99001 (http: // localhost: 99001/index.html).

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, entendi:

    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 por que estou recebendo esse erro?

Foi útil?

Solução

Você não pode fazer um cruzamento xmlHttPrequest, a única "opção" seria uma técnica chamada JSONP, que se resume a isso:

Para iniciar a solicitação: adicione um novo <script> Tag com o URL remoto e verifique se o URL remoto retorna um arquivo JavaScript válido que chama sua função de retorno de chamada. Alguns serviços suportam isso (e permitem nomear seu retorno de chamada em um parâmetros GET).

A outra saída fácil seria criar um "proxy" no servidor local, que recebe a solicitação remota e, em seguida, apenas a "encaminhará" para o seu JavaScript.

Editar/Adicionar:

Vejo que o JQuery tem suporte embutido para o JSONP, verificando se o URL contém "retorno de chamada =?" (onde o jQuery substituirá? pelo método real de retorno de chamada). Mas você ainda precisa processar isso no servidor remoto para gerar uma resposta válida.

Outras dicas

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

Buscle 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 eu não acredito ter sido 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 de texto codificado por formulários/URL, 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 o 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"));
}

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

E não se esqueça no 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 isto ajude.

Estou usando o Webapi 3 e estava enfrentando o mesmo problema. O problema foi resolvido, pois @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.

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

Obrigado pela sua solução @rytis!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top