As solicitações jQuery Ajax estão sendo canceladas sem serem enviadas

87

Estou tentando conectar um script ao aplicativo World-Wide Telescope da Microsoft. Este último escuta na porta 5050 os comandos. Ele está rodando na mesma máquina que o navegador (Chrome agora, mas pelo que eu posso dizer, o comportamento é o mesmo com Firefox 7 e IE 9).

Estou enviando um cabeçalho "Access-Control-Allow-Origin: *" com o arquivo html original para tentar eliminar as restrições de XSS como meu problema.

Meu código para acessar a WWT é o seguinte:

$.ajax({
    type: 'POST',
    url: url,
    data: data,
    crossDomain: true,
    success: success,
    dataType: dataType
});

url neste caso é "http: //127.0.0.1: 5050 / layerApi.aspx? cmd = new & ..." (obviamente ... é uma abreviação aqui para alguns parâmetros adicionais).

Olhando para o diagnóstico de rede no Chrome, posso ver o seguinte:

Request URL:http://127.0.0.1:5050/layerApi.aspx?cmd=new&...
Request Headersview source
Accept:application/xml, text/xml, */*; q=0.01
Content-Type:application/x-www-form-urlencoded
Origin:http://gwheeler4
Referer:http://gwheeler4/conceptconnect.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1

O pedido está saindo - vejo o WWT fazer uma nova camada. No entanto, não recebo uma chamada de retorno. Se eu adicionar um retorno de chamada de erro que é chamado, mas a propriedade de erro no objeto jqXHR é apenas "erro" e o status é 0. Se eu olhar a solicitação de rede no Chrome, vejo "(cancelado)" como o status e nenhuma resposta .

Se eu pegar o mesmo URL e colá-lo em uma nova guia do navegador, posso ver que a resposta é o XML esperado.

Claro, uma diferença aqui é que este é um GET, não um POST, mas eu tentei isso no meu script e não faz diferença.

Estou muito perplexo com isso e gostaria de receber novas ideias.

Graham Wheeler
fonte
Você já tentou manipular o errorretorno de chamada para ver se ele está retornando com um erro?
StriplingWarrior
1
"Estou enviando um cabeçalho" Access-Control-Allow-Origin: * "com o arquivo html original para tentar eliminar as restrições de XSS como meu problema." Você quer dizer que o servidor está enviando de volta o cabeçalho Access-Control-Origin? Ou que você está enviando junto com a solicitação Ajax?
Jason Dean
tente acessar a página diretamente através do url e veja se você está conseguindo alguma saída
zod
1
Sim, recebo um retorno de chamada de erro com o texto de status "" e o código 0. Este não é um problema do jQuery; Reescrevi o código usando um XHR direto e obtenho o mesmo resultado - ou seja, um readyState de 4 com um request.status de zero e um request.responseText vazio. O cabeçalho Access-Control-Allow-Origin está sendo enviado pelo servidor. Acessar a página diretamente por meio do URL retorna a resposta XML esperada.
Graham Wheeler

Respostas:

134

Se alguém se deparar com isso, o problema que tivemos era que estávamos fazendo a solicitação ajax de um link e não impedindo que o link fosse seguido. Portanto, se você estiver fazendo isso em um onclickatributo, certifique-se return false;também.

Kazetsukai
fonte
Isso funcionou para mim também. Obrigado. Esqueci por que estava retornando falso em meu manipulador onClick e mudei para verdadeiro e, depois de ler sua postagem, de repente me dei conta.
Shiprack,
4
Além disso, se você estiver usando um formulário, será necessário adicionar o return falseno final de seu onsubmitatributo.
Jason Axelson
8
@VincentClyde "return false;"diz aos formulários e links para abortar a ação. Isso foi originalmente planejado para validação de formulário javascript, onde uma função de validação retornaria falso se o formulário fosse inválido, interrompendo o envio do formulário.
Tyzoid
13
Você também pode usar e.preventDefault();, onde eé o onclickparâmetro do evento.
Hannele de
1
@Hannele Muito obrigado por compartilhar event.preventDefault. Eu precisava tanto disso. Não vejo nenhuma outra resposta sugerindo isso. Você deve postar isso como uma resposta separada.
Mohit de
112

Se você estiver usando o Chrome, não verá informações suficientes no painel de rede padrão do Chrome para determinar a causa raiz de uma (canceled)solicitação.

Você precisa usar o chrome://net-internals/#eventsque irá mostrar os detalhes sangrentos da solicitação que você está enviando - incluindo redirecionamentos ocultos / informações de segurança sobre o envio de cookies, etc.

por exemplo, o seguinte mostra um redirecionamento que eu não estava vendo no rastreamento de rede - causado por meus cookies não serem enviados entre subdomínios:

t=1374052796448 [st=  1]   +URL_REQUEST_START_JOB  [dt=261]
                            --> load_flags = 143540481 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | ENABLE_LOAD_TIMING | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VALIDATE_CACHE | VERIFY_EV_CERT)
                            --> method = "GET"
                            --> priority = 2
                            --> url = "https://...."
...
t=1374052796708 [st=261]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS
                                --> HTTP/1.1 302 Moved Temporarily
                                    Content-Type: text/html
                                    Date: Wed, 17 Jul 2013 09:19:56 GMT
...
t=1374052796709 [st=262]     +URL_REQUEST_BLOCKED_ON_DELEGATE  [dt=0]
t=1374052796709 [st=262]        CANCELLED
t=1374052796709 [st=262]   -URL_REQUEST_START_JOB
                            --> net_error = -3 (ERR_ABORTED)
Ben Walding
fonte
Também tenho um problema (cancelado). @Ben, foi legal saber mais sobre esse rastreamento, infelizmente ele não forneceu nenhuma informação. O servidor no meu caso é S3 e o cors está configurado no meu balde. Tudo o que estou fazendo é um simples GET para uma imagem. Vejo em um painel de rede uma solicitação com o cabeçalho Origin, mas sem resposta. Aparentemente, o Chrome cancela a solicitação antes de enviá-la ao servidor. Sem redirecionamentos, sem https, sem comprimento de conteúdo 0. Batendo minha cabeça o dia todo, ainda é um mistério.
Gene Vayngrib de
@GeneVayngrib Experimente o Firefox - o depurador de rede mostrará diretamente mais informações - talvez você consiga resolver o problema aí e fazê-lo funcionar no Chrome.
Ben Walding
@BenW obrigado, mas o Firefox não tem nenhum problema com esta imagem que é servida pelo Amazon S3.
Gene Vayngrib
YUPP. Isso ajudou muito!
rubmz
21

No meu caso, eu estava tendo type='submit'isso quando estava enviando o formulário, a página estava recarregando antes que o ajax fosse acionado, então uma solução simples era ter type="button". Se você não especificar um tipo, ele é o submitpadrão, então você deve especificartype="button"

type='submit' => type='button'

OU

Sem tipo => type='button'

Mamba negra
fonte
3
necro postando aqui, processe-me stackoverflow. Estive pesquisando em todos os lugares o dia todo por que meu pedido funciona no console, mas não no script, e essa foi a resposta .. obrigado !!!
pcort
1
Eu entrei e encontrei este tópico novamente para votar a favor desta resposta !!, isso ajudou muito. estava quebrando minha cabeça por horas
dev
Jai shree Krishna, espero que ajude muitos a vir. E eles descobrem antes.
Black Mamba
6

Eu tive um problema parecido. No meu caso, estou tentando usar um serviço web em um servidor apache + django (o serviço foi escrito por mim). Eu estava tendo a mesma saída que você: Chrome diz que foi cancelado enquanto FF faz tudo certo. Se eu tentasse acessar o serviço diretamente no navegador em vez de no ajax, também funcionaria. Procurando no Google, descobri que algumas versões mais recentes do apache não estavam definindo o comprimento da resposta corretamente nos cabeçalhos de resposta, então fiz isso manualmente. Com o django, tudo que eu precisava fazer era:

response['Content-Length'] = len(content)

Se você tiver controle sobre o serviço que está tentando acessar, descubra como modificar o cabeçalho de resposta na plataforma que está usando, caso contrário, você terá que entrar em contato com o provedor de serviços para corrigir esse problema. Aparentemente, o FF e muitos outros navegadores são capazes de lidar com essa situação corretamente, mas os designers do Chrome decidiram fazê-lo conforme especificado.

Felipe Sodre Silva
fonte
Tentei definir o cabeçalho de comprimento do conteúdo e ainda tenho o mesmo problema descrito na pergunta original. Estou usando PHP 5.3.8 e Apache 2.2.21 (usando WAMP no Windows 7)
rodrigo-silveira
4

Eu tive uma questão semelhante. Usando chrome: // net-internals / # events, pude ver que meu problema era devido a algum redirecionamento silencioso. Minha solicitação get estava sendo acionada em um script onload. O url estava no formato " http://example.com/inner-path " e o 301 estava redirecionando permanentemente para "/ caminho interno". Para corrigir o problema, apenas alterei o url para "/ caminho interno" e isso corrigiu o problema. Ainda não sei por que um script que funcionou há uma semana estava me causando problemas ... Espero que isso ajude alguém

RedEight
fonte
3

(Usando Web Forms ASP.NET)

Meu problema era que eu estava tentando disparar o Ajax do evento de clique de um botão de envio que tinha uma configuração de evento de clique do lado do servidor. Tive que tornar o botão apenas um botão simples (ou seja <input type="button">)

contactmatt
fonte
Muito obrigado.
Farheen Nilofer
3

Eu tive o mesmo problema, para mim estava criando o iframe de maneira temporária e estava removendo o iframe antes que o ajax fosse concluído, então o navegador cancelaria minha solicitação de ajax.

Reza
fonte
Como você resolveu esse problema? Meu site está sendo incorporado em um iframe não controlado por mim. Quero que minha chamada seja concluída, pois faz algumas configurações de dados de segundo plano
Rips
@Rips isso é de 4 anos atrás, de qualquer maneira acho que resolvi usando Promises
Reza
3

Expandindo a resposta de @ Kazetsukai, você pode encontrar este problema se estiver fazendo sua solicitação AJAX do usuário clicando em um link.

Se você configurar seu link assim:

<a href="#" onclick="soAjax()">click me!</a>

E então um manipulador de javascript como o seguinte:

soAjax() {
    $.ajax({ ... all your lovely parameters ... });       
}

Para evitar que seu navegador siga o link e cancele qualquer solicitação em andamento, você deve adicionar return falseou e.preventDefault()interromper a propagação do evento de clique:

soAjax() {
   $.ajax({ ... etc ... });
   return false;
}

Ou:

soAjax(e) {
   $.ajax({ ... etc ... });
   e.preventDefault();
}
Hannele
fonte
2

Duas possibilidades existem quando a solicitação AJAX é descartada (se não a solicitação de origem cruzada):

  1. Você não está impedindo o comportamento padrão do elemento para o evento.
  2. Você definiu o tempo limite de AJAX muito baixo ou o servidor de back-end da rede / aplicativo está lento.

Solução para 1) : Adicionar return false;ou e.preventDefault();no manipulador de eventos.

Solução para 2) : Adicionar opção de tempo limite ao formar a solicitação AJAX. Exemplo abaixo.

$.ajax({
    type: 'POST',
    url: url,
    timeout: 86400,
    data: data,
    success: success,
    dataType: dataType
});

Para solicitações de origem cruzada, verifique os cabeçalhos HTTP de Compartilhamento de recursos de origem cruzada (CORS).

AnkitK
fonte
1

Recebi este erro ao fazer uma solicitação usando http para um url que exigia https. Acho que a chamada ajax não está lidando com o redirecionamento. Esse é o caso mesmo com a opção crossDomain ajax definida como true (no JQuery 1.5.2).

ptutt
fonte
0

No meu caso, o mod-rewrite do Apache estava combinando o url e redirecionando a solicitação para https.

Observe a solicitação em chrome: // net-internals / # events.

Ele mostrará um log interno da solicitação. Verifique se há redirecionamentos.

bbrame
fonte
0

Eu tive o mesmo problema, mas no meu caso acabou sendo um problema de cookie. Os caras que trabalham no back-end mudaram o caminho do cookie JSESSIONID que é definido quando fazemos login em nosso aplicativo, e eu tinha um cookie antigo com esse nome no meu computador, mas com o caminho antigo. Então quando tentei logar no navegador (Chrome) mandei dois cookies chamados JSESSIONID, com valores diferentes, para o servidor - o que compreensivelmente o confundiu - então ele cancelou a solicitação. Excluir os cookies do meu computador corrigiu isso.

Joe Dyndale
fonte
0

Eu tive esse erro de uma forma mais assustadora: a guia de rede e os eventos chrome: // net-internals / # não mostraram a solicitação após o js ser concluído. Ao pausar o js no callcack de erro, a guia de rede mostrou a solicitação como (cancelada). O foi consistentemente chamado para exatamente uma (sempre a mesma) de várias solicitações semelhantes em uma página da web. Depois de reiniciar o Chrome o erro não voltou a surgir!

cristão
fonte
0

Tive o cancelado no Firefox . Algumas chamadas de ajax funcionaram perfeitamente bem para mim, mas falharam para o colega de trabalho que realmente precisava usá-las.

Quando verifiquei isso por meio dos truques do Chrome mencionados acima, não encontrei nada suspeito. Ao verificar no firebug, ele mostrou a animação de 'carregamento' após as duas chamadas maléficas, e nenhuma guia de resultado.

A solução foi mega simples: vá para a história, encontre o site, clique com o botão direito do mouse -> esqueça o site.
Esqueça, não exclua.

Depois disso, sem problemas mais. Meu palpite é que tem algo a ver com o .htaccess.

Martijn
fonte
0

No meu caso, era a barra final que faltava no url. Adicionar a barra final resolveu meu problema.

Aftab Baig
fonte
0

Para o caso Dropzone.js. No meu caso, isso foi causado porque o valor da timeoutopção era muito baixo por padrão. Portanto, aumente de acordo com suas necessidades.

{
// other dropzone options
timeout: 60000 * 10, // 10 minutes
...
}
Scofield
fonte
-1

Tive esse problema com uma rede 3G específica.
Ele sempre falhava em solicitações DELETE com net_error = -101in chrome: // net-internals / # events.

Outras redes funcionaram bem, então presumo que havia um servidor proxy com defeito ou algo assim.

Dan Abramov
fonte