Javascript jQuery Ajax Edição: Post funciona bem no Firefox, ou seja, Safari, mas não Chrome
-
16-09-2019 - |
Pergunta
Sou novo no JavaScript e trabalhando em um projeto de hobby com alguns desenvolvedores. Temos uma página simples usada para enviar solicitações a um banco de dados.
Decidi tentar aprender jQuery e comecei a implementar algumas funcionalidades do AJAX nesta página de solicitação. Funciona bem no Firefox, IE e Safari, mas, por algum motivo estranho, não consigo fazê -lo funcionar no Chrome.
Estou depurado há algumas horas e não tenho idéia de por que não está funcionando. Aqui está a parte relevante do formulário HTML (pós -ação removida devido ao JavaScript):
<form method="POST">
<input type="text" name="amount" value="0" size="7" />
<input type="submit" value="Fulfill!" /><br />
<input type="hidden" name="index" value="69" />
<input type="hidden" name="item" value="Iron Ore" />
</form>
E aqui está o formulário de PHP para o qual ele publica:
<?php
require_once("../classes/Database.php");
$database = new Database();
$amount = $database->sanitizeString($_POST['amount']);
$index = $database->sanitizeString($_POST['index']);
$username = $database->sanitizeString($_POST['username']);
$item = $database->sanitizeString($_POST['item']);
$database->connect();
$database->setRequest($amount, $index, $username, $item);
$database->setKarma($username, $amount, $item);
?>
E o mais importante, aqui está o meu código JavaScript novato que está simplesmente no arquivo HTML:
<script language="JavaScript">
var amount = 0;
var index = 0;
var item = 0;
var username = "";
var data = "";
$(document).ready(function(){
$("form input[type=submit]").click(function(){
amount = $(this).siblings("input[name=amount]").val();
index = $(this).siblings("input[name=index]").val();
item = $(this).siblings("input[name=item]").val();
username = "<?=$_SESSION['username']; ?>";
//var stuff = $.post("pages/ajaxfulfill.php", {amount:amount,index:index,item:item, username:username}, function(data){alert(data)}, "html");
var stuff = $.ajax(
{
url: "pages/ajaxfulfill.php",
type: "POST", data:"amount=" + amount + "&index=" + index + "&item=" + item + "&username=" + username,
success: function(data)
{
alert("Success")
},
error: function (XMLHttpRequest, textStatus, errorThrown)
{
alert("error" + XMLHttpRequest.status);
alert("error" + XMLHttpRequest.responseText);
}
}
)
$(this).parents("td").text("Submitted");
});
});
</script>
No começo, eu estava usando a função comentada $. Post, que funciona com os navegadores mencionados acima. Tentei mudar para a função $ .ajax durante meu processo de depuração e descobri que FF, IE e Safari sempre retornam um alerta de "sucesso", enquanto o Chrome está retornando um erro com o status 0 e uma resposta em branco.
Sendo um novato em JavaScript, estou completamente perdido com o motivo pelo qual isso falharia. Se alguém puder me apontar na direção certa, você terá meu profundo respeito e desejos bem. Obrigado.
Solução
Você não parece impedir a ação padrão no botão Enviar. Portanto, após o seu clique, o formulário ainda é submetido, presumivelmente cancelando seu xmlHttPrequest.
(O que pode fazer a diferença entre navegador aqui é que, no final da função, você remove o formulário da página chamando o text()
função. Isso deve parar o formulário ser enviado? Não sei ... alguns navegadores podem, mas não há especificação que diga.)
Usar event.preventDefault();
no argumento passou para o manipulador function(event) { ... }
Para parar o botão, clique em passar para enviar o formulário.
Mas não vincule o código de envio do formulário a um botão de entrada. Seu script pode (dependendo do navegador e de outros atributos do formulário) falhar ao disparar em outro tipo de envio, como uma inspeção. Sempre vincule a validação e a substituição de forma de Ajax usando o submit
evento no form
em si. event.preventDefault();
ainda se aplica.
Omitindo o action
atributo de a <form>
é inválido; O navegador normalmente escolhe o URL da página existente para se enviar. Se você deseja formar campos sem um formulário para enviar (e você não precisa de entradas de rádio), basta omitir o <form>
elemento. Mas, na verdade, você deve estar usando aprimoramento progressivo: faça o formulário funcionar de HTML simples primeiro, com um adequado method="POST" action="ajaxfulfill.php"
, e então Crie uma função trivial de Ajax em cima disso.
username = "<?=$_SESSION['username']; ?>";
Injeção de script. Em vez de:
username= <?= json_encode($_SESSION['username'], JSON_HEX_TAG); ?>
E:
data:"amount=" + amount + "&index=" + index + "&item=" + item + "&username=" + username,
Você precisaria usar encodeURIComponent(...)
sobre cada um dos valores em uma submissão de forma codificada por URL, ou caracteres especiais o quebrarão. Melhor deixar o jQuery fazer isso por você:
data: {amount: amount, index: index, item: item, username: username},
ou ainda mais simples, solte toda a leitura manual de field.val()
e apenas use o existente serializar função que faz tudo isso por você:
data: $(this).serialize(),
(Assumindo this
agora é o form
você está lidando onsubmit
para ... se fosse o botão Enviar, você teria que dizer $(this.form)
.)
Você realmente quer receber o nome de usuário dos dados postais submitidos pelo usuário, que eles podem ter alterado? A menos que os nomes de usuário sejam deliberadamente livres de segurança, parece uma idéia melhor obtê-la da sessão de onde veio.
Outras dicas
A primeira coisa que você precisa fazer é isolar o problema. Chrome v4.0.249.27 (no OS X, pelo menos) vem com ferramentas de desenvolvedor que você provavelmente achará útil. Veja o que o Chrome está fazendo quando clicar nesse botão. Você também pode querer adicionar ".ajax" à lista de "expressões assistidas" na guia "scripts" das ferramentas do desenvolvedor.
As ferramentas do desenvolvedor podem ser encontradas através Visão » Desenvolvedor » Ferramentas de desenvolvimento.
Você pode fazer algumas coisas para diagnosticar você mesmo:
- Shift + Ctrl + J no Chrome para iniciar o console JavaScript e ativar a depuração. Faça pontos de interrupção e entre na sua função
- Assista ao console de erro/aviso JavaScript (mesmo em seus outros navegadores)
Sei que este é um post antigo, mas tive sintomas semelhantes no meu projeto e acabei aqui tentando encontrar uma solução.
Eu segui alguns dos conselhos aqui sobre a depuração e percebi que o Chrome não atualiza o mesmo que outros navegadores. As alterações que fiz no código JS e o CSS foram instantaneamente atualizadas no Safari e no Firefox com uma atualização normal, mas o Chrome precisa de um recarregar e o cache claro antes de atualizar os mesmos itens.
Não estou dizendo que essa é a cura para todos os problemas mencionados acima, mas resolveu meu problema.