【问题标题】:JavaScript JQuery Ajax Issue: POST Works fine in Firefox, IE, Safari but not ChromeJavaScript JQuery Ajax 问题:POST 在 Firefox、IE、Safari 但不是 Chrome
【发布时间】:2009-12-08 02:05:40
【问题描述】:

我是 JavaScript 新手,正在与一些开发人员一起从事一个业余项目。我们有一个简单的页面,用于向数据库提交请求。

我决定尝试学习 JQuery,并开始在这个请求页面中实现一些 AJAX 功能。它在 FireFox、IE 和 Safari 中运行良好,但由于某些奇怪的原因,我无法让它在 Chrome 中运行。

我已经调试了几个小时了,但我不知道为什么它不起作用。这是 HTML 表单的相关部分(由于 JavaScript 删除了 post 操作):

        <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>

这是它发布到的 PHP 表单:

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

最重要的是,这是我的新手 JavaScript 代码,它只是在 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>

起初,我使用的是注释掉的 $.post 函数,它适用于上述浏览器。我在调试过程中尝试切换到 $.ajax 函数,发现 FF、IE 和 Safari 总是返回“成功”警报,而 Chrome 返回状态为 0 的错误和空白响应。

作为一个 JavaScript 新手,我完全不知道为什么会失败。如果有人能指出我正确的方向,我将向您致以崇高的敬意和良好的祝愿。谢谢。

【问题讨论】:

  • 与问题没有直接关系,但考虑在将字符串发送到 JavaScript 之前转义字符串。在这种情况下,例如 (a) 您的代码会因任何包含撇号的用户名而中断,并且 (b) 用户将能够使用足够聪明的用户名在您的 javascript 中注入任意代码,从而利用 XSS 漏洞。
  • 对不起,它不是撇号,在这种情况下它是一个引号,但其余部分仍然适用。
  • DrJokepu,感谢您指出这一点。我正在清理与 PHP 相关的内容,但完全忘记了清理与 JavaScript 相关的输入。
  • 下面的好人向我展示了如何调试,但我现在更加困惑——当我调试它时,脚本运行良好。当我逐行浏览代码时,它完美无缺。当它运行时,它会失败。这是什么意思?!
  • 正在服务的 XMLHttpRequest 与您因提交表单而卸载页面之间存在竞争条件。单步执行会延迟提交,直到 XHR 的响应准备好之后。

标签: javascript jquery google-chrome http-post


【解决方案1】:

您似乎没有阻止提交按钮上的默认操作。所以在你的点击函数触发后,表单仍然提交,大概取消了你的 XMLHttpRequest。

(在这里跨浏览器可能会有所不同的是,在函数结束时,您通过调用text() 函数从页面中删除表单。这是否应该停止提交表单?不知道.. . 一些浏览器可能会这样,但没有规范说明。)

在传递给处理程序 function(event) { ... } 的参数上使用 event.preventDefault(); 以停止按钮单击以提交表单。

但不要将表单提交代码绑定到输入按钮。您的脚本可能(取决于浏览器和表单的其他属性)无法在其他类型的提交(例如 Enter 按下)上触发。始终使用form 本身上的submit 事件绑定验证和AJAX-form-replacement。 event.preventDefault(); 仍然适用。

省略&lt;form&gt;action 属性无效;浏览器通常选择现有页面的 URL 来提交。如果您想要提交没有表单的表单字段(并且您不需要单选输入),只需省略 &lt;form&gt; 元素。但实际上您应该使用渐进增强:首先使用纯 HTML 使表单工作,使用适当的method="POST" action="ajaxfulfill.php",然后然后在此之上构建一个简单的 AJAX 函数。

username = "<?=$_SESSION['username']; ?>";

脚本注入。而是:

username= <?= json_encode($_SESSION['username'], JSON_HEX_TAG); ?>

还有:

data:"amount=" + amount + "&index=" + index + "&item=" + item + "&username=" + username,

您需要在 URL-encoded-form-submission 中的每个值上使用 encodeURIComponent(...),否则特殊字符会破坏它。最好让 jQuery 为你做这件事:

data: {amount: amount, index: index, item: item, username: username},

或者更简单,放弃所有手动阅读 field.val() 并使用现有的 serialize 函数为您完成这一切:

data: $(this).serialize(),

(假设this 现在是form,您正在处理onsubmit ……如果是提交按钮,您必须说$(this.form)。)

您真的想从用户提交的 POST 数据中获取用户名吗?他们可能已经更改了这些数据?除非用户名是故意不安全的,否则从它出现的会话中获取它似乎是一个更好的主意。

【讨论】:

  • 先生,您是绅士和天才。我修改了我的脚本并让它工作。我已将您的其他建议铭记于心,并将相应地修改我的脚本。感谢您的帮助。
  • 哇。谢谢你!!我只花了 3 个小时试图弄清楚发生了什么,你的帖子在 1 秒内修复了它。谢谢!
【解决方案2】:

您需要做的第一件事是隔离问题。 Chrome v4.0.249.27(至少在 OS X 上)附带了您可能会发现有用的开发人员工具。当您单击该按钮时,请查看 Chrome 正在执行的操作。您可能还想将“.ajax”添加到开发人员工具的“脚本”选项卡中的“监视表达式”列表中。

开发者工具可以通过View » Developer » Developer Tools找到。

【讨论】:

    【解决方案3】:

    您可以做一些事情来自己诊断:

    1. 在 Chrome 中使用 Shift + Ctrl + J 启动 Javascript 控制台并启用调试。粘贴断点并逐步执行您的函数
    2. 观看 Javascript 错误/警告控制台(即使在您的其他浏览器中)

    【讨论】:

    • 谢谢。今天之前我从未使用过 Chrome,所以我对此一无所知。但有一件事让我更加困惑。我逐行调试它,遍历每个表达式。当我以这种方式调试它时,代码可以工作!但是,当我在没有调试的情况下运行它时,它会失败?!这是什么意思?
    • @foo 它可以工作,因为单步执行代码可以让表单有时间在将其从 DOM 中删除之前提交自己
    【解决方案4】:

    我意识到这是一篇旧帖子,但我刚刚在我的项目中遇到了类似的症状,最终在这里试图找到解决方案。

    我遵循了此处有关调试的一些建议,并意识到 Chrome 不会像其他浏览器那样更新。我在 js 代码中所做的更改,并且 css 在 Safari 和 Firefox 中通过正常刷新立即更新,但 Chrome 需要在更新这些相同项目之前进行硬重新加载和缓存清除。

    我并不是说这是解决上述所有问题的方法,但它解决了我的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多